}
-/*
- * 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.
*
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);
*/
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))
{
/* 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)
{
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.
/* internal vars */
char *restrict_env;
-typedef BOOL (WINAPI * __CreateRestrictedToken) (HANDLE, DWORD, DWORD, PSID_AND_ATTRIBUTES, DWORD, PLUID_AND_ATTRIBUTES, DWORD, PSID_AND_ATTRIBUTES, PHANDLE);
-
/* Windows API define missing from some versions of MingW headers */
#ifndef DISABLE_MAX_PRIVILEGE
#define DISABLE_MAX_PRIVILEGE 0x1
HANDLE restrictedToken;
SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY};
SID_AND_ATTRIBUTES dropSids[2];
- __CreateRestrictedToken _CreateRestrictedToken;
- HANDLE Advapi32Handle;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
- Advapi32Handle = LoadLibrary("ADVAPI32.DLL");
- if (Advapi32Handle == NULL)
- {
- pg_log_error("could not load library \"%s\": error code %lu",
- "ADVAPI32.DLL", GetLastError());
- return 0;
- }
-
- _CreateRestrictedToken = (__CreateRestrictedToken) (pg_funcptr_t) GetProcAddress(Advapi32Handle, "CreateRestrictedToken");
-
- if (_CreateRestrictedToken == NULL)
- {
- pg_log_error("cannot create restricted tokens on this platform: error code %lu",
- GetLastError());
- FreeLibrary(Advapi32Handle);
- return 0;
- }
-
/* Open the current token to use as a base for the restricted one */
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &origToken))
{
pg_log_error("could not open process token: error code %lu",
GetLastError());
- FreeLibrary(Advapi32Handle);
return 0;
}
pg_log_error("could not allocate SIDs: error code %lu",
GetLastError());
CloseHandle(origToken);
- FreeLibrary(Advapi32Handle);
return 0;
}
- b = _CreateRestrictedToken(origToken,
- DISABLE_MAX_PRIVILEGE,
- sizeof(dropSids) / sizeof(dropSids[0]),
- dropSids,
- 0, NULL,
- 0, NULL,
- &restrictedToken);
+ b = CreateRestrictedToken(origToken,
+ DISABLE_MAX_PRIVILEGE,
+ sizeof(dropSids) / sizeof(dropSids[0]),
+ dropSids,
+ 0, NULL,
+ 0, NULL,
+ &restrictedToken);
FreeSid(dropSids[1].Sid);
FreeSid(dropSids[0].Sid);
CloseHandle(origToken);
- FreeLibrary(Advapi32Handle);
if (!b)
{