Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 47bd0b3

Browse files
committed
Replace load of functions by direct calls for some WIN32
This commit changes the following code paths to do direct system calls to some WIN32 functions rather than loading them from an external library, shaving some code in the process: - Creation of restricted tokens in pg_ctl.c, introduced by a25cd81. - QuerySecurityContextToken() in auth.c for SSPI authentication in the backend, introduced in d602592. - CreateRestrictedToken() in src/common/. This change is similar to the case of pg_ctl.c. Most of these functions were loaded rather than directly called because, as mentioned in the code comments, MinGW headers were not declaring them. I have double-checked the recent MinGW code, and all the functions changed here are declared in its headers, so this change should be safe. Note that I do not have a MinGW environment at hand so I have not tested it directly, but that MSVC was fine with the change. The buildfarm will tell soon enough if this change is appropriate or not for a much broader set of environments. A few code paths still use GetProcAddress() to load some functions: - LDAP authentication for ldap_start_tls_sA(), where I am not confident that this change would work. - win32env.c and win32ntdll.c where we have a per-MSVC version dependency for the name of the library loaded. - crashdump.c for MiniDumpWriteDump() and EnumDirTree(), where direct calls were not able to work after testing. Reported-by: Thomas Munro Reviewed-by: Justin Prysby Discussion: https://postgr.es/m/CA+hUKG+BMdcaCe=P-EjMoLTCr3zrrzqbcVE=8h5LyNsSVHKXZA@mail.gmail.com
1 parent df4a056 commit 47bd0b3

File tree

3 files changed

+47
-158
lines changed

3 files changed

+47
-158
lines changed

src/backend/libpq/auth.c

+1-28
Original file line numberDiff line numberDiff line change
@@ -1201,11 +1201,8 @@ pg_SSPI_recvauth(Port *port)
12011201
DWORD accountnamesize = sizeof(accountname);
12021202
DWORD domainnamesize = sizeof(domainname);
12031203
SID_NAME_USE accountnameuse;
1204-
HMODULE secur32;
12051204
char *authn_id;
12061205

1207-
QUERY_SECURITY_CONTEXT_TOKEN_FN _QuerySecurityContextToken;
1208-
12091206
/*
12101207
* Acquire a handle to the server credentials.
12111208
*/
@@ -1358,36 +1355,12 @@ pg_SSPI_recvauth(Port *port)
13581355
*
13591356
* Get the name of the user that authenticated, and compare it to the pg
13601357
* username that was specified for the connection.
1361-
*
1362-
* MingW is missing the export for QuerySecurityContextToken in the
1363-
* secur32 library, so we have to load it dynamically.
13641358
*/
13651359

1366-
secur32 = LoadLibrary("SECUR32.DLL");
1367-
if (secur32 == NULL)
1368-
ereport(ERROR,
1369-
(errmsg("could not load library \"%s\": error code %lu",
1370-
"SECUR32.DLL", GetLastError())));
1371-
1372-
_QuerySecurityContextToken = (QUERY_SECURITY_CONTEXT_TOKEN_FN) (pg_funcptr_t)
1373-
GetProcAddress(secur32, "QuerySecurityContextToken");
1374-
if (_QuerySecurityContextToken == NULL)
1375-
{
1376-
FreeLibrary(secur32);
1377-
ereport(ERROR,
1378-
(errmsg_internal("could not locate QuerySecurityContextToken in secur32.dll: error code %lu",
1379-
GetLastError())));
1380-
}
1381-
1382-
r = (_QuerySecurityContextToken) (sspictx, &token);
1360+
r = QuerySecurityContextToken(sspictx, &token);
13831361
if (r != SEC_E_OK)
1384-
{
1385-
FreeLibrary(secur32);
13861362
pg_SSPI_error(ERROR,
13871363
_("could not get token from SSPI security context"), r);
1388-
}
1389-
1390-
FreeLibrary(secur32);
13911364

13921365
/*
13931366
* No longer need the security context, everything from here on uses the

src/bin/pg_ctl/pg_ctl.c

+39-98
Original file line numberDiff line numberDiff line change
@@ -1724,17 +1724,6 @@ pgwin32_doRunAsService(void)
17241724
}
17251725

17261726

1727-
/*
1728-
* Mingw headers are incomplete, and so are the libraries. So we have to load
1729-
* a whole lot of API functions dynamically.
1730-
*/
1731-
typedef BOOL (WINAPI * __CreateRestrictedToken) (HANDLE, DWORD, DWORD, PSID_AND_ATTRIBUTES, DWORD, PLUID_AND_ATTRIBUTES, DWORD, PSID_AND_ATTRIBUTES, PHANDLE);
1732-
typedef BOOL (WINAPI * __IsProcessInJob) (HANDLE, HANDLE, PBOOL);
1733-
typedef HANDLE (WINAPI * __CreateJobObject) (LPSECURITY_ATTRIBUTES, LPCTSTR);
1734-
typedef BOOL (WINAPI * __SetInformationJobObject) (HANDLE, JOBOBJECTINFOCLASS, LPVOID, DWORD);
1735-
typedef BOOL (WINAPI * __AssignProcessToJobObject) (HANDLE, HANDLE);
1736-
typedef BOOL (WINAPI * __QueryInformationJobObject) (HANDLE, JOBOBJECTINFOCLASS, LPVOID, DWORD, LPDWORD);
1737-
17381727
/*
17391728
* Set up STARTUPINFO for the new process to inherit this process' handles.
17401729
*
@@ -1777,20 +1766,11 @@ CreateRestrictedProcess(char *cmd, PROCESS_INFORMATION *processInfo, bool as_ser
17771766
STARTUPINFO si;
17781767
HANDLE origToken;
17791768
HANDLE restrictedToken;
1769+
BOOL inJob;
17801770
SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY};
17811771
SID_AND_ATTRIBUTES dropSids[2];
17821772
PTOKEN_PRIVILEGES delPrivs;
17831773

1784-
/* Functions loaded dynamically */
1785-
__CreateRestrictedToken _CreateRestrictedToken = NULL;
1786-
__IsProcessInJob _IsProcessInJob = NULL;
1787-
__CreateJobObject _CreateJobObject = NULL;
1788-
__SetInformationJobObject _SetInformationJobObject = NULL;
1789-
__AssignProcessToJobObject _AssignProcessToJobObject = NULL;
1790-
__QueryInformationJobObject _QueryInformationJobObject = NULL;
1791-
HANDLE Kernel32Handle;
1792-
HANDLE Advapi32Handle;
1793-
17941774
ZeroMemory(&si, sizeof(si));
17951775
si.cb = sizeof(si);
17961776

@@ -1802,20 +1782,6 @@ CreateRestrictedProcess(char *cmd, PROCESS_INFORMATION *processInfo, bool as_ser
18021782
*/
18031783
InheritStdHandles(&si);
18041784

1805-
Advapi32Handle = LoadLibrary("ADVAPI32.DLL");
1806-
if (Advapi32Handle != NULL)
1807-
{
1808-
_CreateRestrictedToken = (__CreateRestrictedToken) (pg_funcptr_t) GetProcAddress(Advapi32Handle, "CreateRestrictedToken");
1809-
}
1810-
1811-
if (_CreateRestrictedToken == NULL)
1812-
{
1813-
/* Log error if we cannot get the function */
1814-
write_stderr(_("%s: could not locate object function to create restricted token: error code %lu\n"),
1815-
progname, (unsigned long) GetLastError());
1816-
return 0;
1817-
}
1818-
18191785
/* Open the current token to use as a base for the restricted one */
18201786
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &origToken))
18211787
{
@@ -1848,19 +1814,18 @@ CreateRestrictedProcess(char *cmd, PROCESS_INFORMATION *processInfo, bool as_ser
18481814
/* Error message already printed */
18491815
return 0;
18501816

1851-
b = _CreateRestrictedToken(origToken,
1852-
0,
1853-
sizeof(dropSids) / sizeof(dropSids[0]),
1854-
dropSids,
1855-
delPrivs->PrivilegeCount, delPrivs->Privileges,
1856-
0, NULL,
1857-
&restrictedToken);
1817+
b = CreateRestrictedToken(origToken,
1818+
0,
1819+
sizeof(dropSids) / sizeof(dropSids[0]),
1820+
dropSids,
1821+
delPrivs->PrivilegeCount, delPrivs->Privileges,
1822+
0, NULL,
1823+
&restrictedToken);
18581824

18591825
free(delPrivs);
18601826
FreeSid(dropSids[1].Sid);
18611827
FreeSid(dropSids[0].Sid);
18621828
CloseHandle(origToken);
1863-
FreeLibrary(Advapi32Handle);
18641829

18651830
if (!b)
18661831
{
@@ -1872,79 +1837,55 @@ CreateRestrictedProcess(char *cmd, PROCESS_INFORMATION *processInfo, bool as_ser
18721837
AddUserToTokenDacl(restrictedToken);
18731838
r = CreateProcessAsUser(restrictedToken, NULL, cmd, NULL, NULL, TRUE, CREATE_SUSPENDED, NULL, NULL, &si, processInfo);
18741839

1875-
Kernel32Handle = LoadLibrary("KERNEL32.DLL");
1876-
if (Kernel32Handle != NULL)
1877-
{
1878-
_IsProcessInJob = (__IsProcessInJob) (pg_funcptr_t) GetProcAddress(Kernel32Handle, "IsProcessInJob");
1879-
_CreateJobObject = (__CreateJobObject) (pg_funcptr_t) GetProcAddress(Kernel32Handle, "CreateJobObjectA");
1880-
_SetInformationJobObject = (__SetInformationJobObject) (pg_funcptr_t) GetProcAddress(Kernel32Handle, "SetInformationJobObject");
1881-
_AssignProcessToJobObject = (__AssignProcessToJobObject) (pg_funcptr_t) GetProcAddress(Kernel32Handle, "AssignProcessToJobObject");
1882-
_QueryInformationJobObject = (__QueryInformationJobObject) (pg_funcptr_t) GetProcAddress(Kernel32Handle, "QueryInformationJobObject");
1883-
}
1884-
1885-
/* Verify that we found all functions */
1886-
if (_IsProcessInJob == NULL || _CreateJobObject == NULL || _SetInformationJobObject == NULL || _AssignProcessToJobObject == NULL || _QueryInformationJobObject == NULL)
1840+
if (IsProcessInJob(processInfo->hProcess, NULL, &inJob))
18871841
{
1888-
/* Log error if we can't get version */
1889-
write_stderr(_("%s: WARNING: could not locate all job object functions in system API\n"), progname);
1890-
}
1891-
else
1892-
{
1893-
BOOL inJob;
1894-
1895-
if (_IsProcessInJob(processInfo->hProcess, NULL, &inJob))
1842+
if (!inJob)
18961843
{
1897-
if (!inJob)
1898-
{
1899-
/*
1900-
* Job objects are working, and the new process isn't in one,
1901-
* so we can create one safely. If any problems show up when
1902-
* setting it, we're going to ignore them.
1903-
*/
1904-
HANDLE job;
1905-
char jobname[128];
1844+
/*
1845+
* Job objects are working, and the new process isn't in one, so
1846+
* we can create one safely. If any problems show up when setting
1847+
* it, we're going to ignore them.
1848+
*/
1849+
HANDLE job;
1850+
char jobname[128];
19061851

1907-
sprintf(jobname, "PostgreSQL_%lu",
1908-
(unsigned long) processInfo->dwProcessId);
1852+
sprintf(jobname, "PostgreSQL_%lu",
1853+
(unsigned long) processInfo->dwProcessId);
19091854

1910-
job = _CreateJobObject(NULL, jobname);
1911-
if (job)
1912-
{
1913-
JOBOBJECT_BASIC_LIMIT_INFORMATION basicLimit;
1914-
JOBOBJECT_BASIC_UI_RESTRICTIONS uiRestrictions;
1915-
JOBOBJECT_SECURITY_LIMIT_INFORMATION securityLimit;
1855+
job = CreateJobObject(NULL, jobname);
1856+
if (job)
1857+
{
1858+
JOBOBJECT_BASIC_LIMIT_INFORMATION basicLimit;
1859+
JOBOBJECT_BASIC_UI_RESTRICTIONS uiRestrictions;
1860+
JOBOBJECT_SECURITY_LIMIT_INFORMATION securityLimit;
19161861

1917-
ZeroMemory(&basicLimit, sizeof(basicLimit));
1918-
ZeroMemory(&uiRestrictions, sizeof(uiRestrictions));
1919-
ZeroMemory(&securityLimit, sizeof(securityLimit));
1862+
ZeroMemory(&basicLimit, sizeof(basicLimit));
1863+
ZeroMemory(&uiRestrictions, sizeof(uiRestrictions));
1864+
ZeroMemory(&securityLimit, sizeof(securityLimit));
19201865

1921-
basicLimit.LimitFlags = JOB_OBJECT_LIMIT_DIE_ON_UNHANDLED_EXCEPTION | JOB_OBJECT_LIMIT_PRIORITY_CLASS;
1922-
basicLimit.PriorityClass = NORMAL_PRIORITY_CLASS;
1923-
_SetInformationJobObject(job, JobObjectBasicLimitInformation, &basicLimit, sizeof(basicLimit));
1866+
basicLimit.LimitFlags = JOB_OBJECT_LIMIT_DIE_ON_UNHANDLED_EXCEPTION | JOB_OBJECT_LIMIT_PRIORITY_CLASS;
1867+
basicLimit.PriorityClass = NORMAL_PRIORITY_CLASS;
1868+
SetInformationJobObject(job, JobObjectBasicLimitInformation, &basicLimit, sizeof(basicLimit));
19241869

1925-
uiRestrictions.UIRestrictionsClass = JOB_OBJECT_UILIMIT_DESKTOP | JOB_OBJECT_UILIMIT_DISPLAYSETTINGS |
1926-
JOB_OBJECT_UILIMIT_EXITWINDOWS | JOB_OBJECT_UILIMIT_READCLIPBOARD |
1927-
JOB_OBJECT_UILIMIT_SYSTEMPARAMETERS | JOB_OBJECT_UILIMIT_WRITECLIPBOARD;
1870+
uiRestrictions.UIRestrictionsClass = JOB_OBJECT_UILIMIT_DESKTOP | JOB_OBJECT_UILIMIT_DISPLAYSETTINGS |
1871+
JOB_OBJECT_UILIMIT_EXITWINDOWS | JOB_OBJECT_UILIMIT_READCLIPBOARD |
1872+
JOB_OBJECT_UILIMIT_SYSTEMPARAMETERS | JOB_OBJECT_UILIMIT_WRITECLIPBOARD;
19281873

1929-
_SetInformationJobObject(job, JobObjectBasicUIRestrictions, &uiRestrictions, sizeof(uiRestrictions));
1874+
SetInformationJobObject(job, JobObjectBasicUIRestrictions, &uiRestrictions, sizeof(uiRestrictions));
19301875

1931-
securityLimit.SecurityLimitFlags = JOB_OBJECT_SECURITY_NO_ADMIN | JOB_OBJECT_SECURITY_ONLY_TOKEN;
1932-
securityLimit.JobToken = restrictedToken;
1933-
_SetInformationJobObject(job, JobObjectSecurityLimitInformation, &securityLimit, sizeof(securityLimit));
1876+
securityLimit.SecurityLimitFlags = JOB_OBJECT_SECURITY_NO_ADMIN | JOB_OBJECT_SECURITY_ONLY_TOKEN;
1877+
securityLimit.JobToken = restrictedToken;
1878+
SetInformationJobObject(job, JobObjectSecurityLimitInformation, &securityLimit, sizeof(securityLimit));
19341879

1935-
_AssignProcessToJobObject(job, processInfo->hProcess);
1936-
}
1880+
AssignProcessToJobObject(job, processInfo->hProcess);
19371881
}
19381882
}
19391883
}
19401884

1941-
19421885
CloseHandle(restrictedToken);
19431886

19441887
ResumeThread(processInfo->hThread);
19451888

1946-
FreeLibrary(Kernel32Handle);
1947-
19481889
/*
19491890
* We intentionally don't close the job object handle, because we want the
19501891
* object to live on until pg_ctl shuts down.

src/common/restricted_token.c

+7-32
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,6 @@
2828
/* internal vars */
2929
char *restrict_env;
3030

31-
typedef BOOL (WINAPI * __CreateRestrictedToken) (HANDLE, DWORD, DWORD, PSID_AND_ATTRIBUTES, DWORD, PLUID_AND_ATTRIBUTES, DWORD, PSID_AND_ATTRIBUTES, PHANDLE);
32-
3331
/* Windows API define missing from some versions of MingW headers */
3432
#ifndef DISABLE_MAX_PRIVILEGE
3533
#define DISABLE_MAX_PRIVILEGE 0x1
@@ -52,36 +50,15 @@ CreateRestrictedProcess(char *cmd, PROCESS_INFORMATION *processInfo)
5250
HANDLE restrictedToken;
5351
SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY};
5452
SID_AND_ATTRIBUTES dropSids[2];
55-
__CreateRestrictedToken _CreateRestrictedToken;
56-
HANDLE Advapi32Handle;
5753

5854
ZeroMemory(&si, sizeof(si));
5955
si.cb = sizeof(si);
6056

61-
Advapi32Handle = LoadLibrary("ADVAPI32.DLL");
62-
if (Advapi32Handle == NULL)
63-
{
64-
pg_log_error("could not load library \"%s\": error code %lu",
65-
"ADVAPI32.DLL", GetLastError());
66-
return 0;
67-
}
68-
69-
_CreateRestrictedToken = (__CreateRestrictedToken) (pg_funcptr_t) GetProcAddress(Advapi32Handle, "CreateRestrictedToken");
70-
71-
if (_CreateRestrictedToken == NULL)
72-
{
73-
pg_log_error("cannot create restricted tokens on this platform: error code %lu",
74-
GetLastError());
75-
FreeLibrary(Advapi32Handle);
76-
return 0;
77-
}
78-
7957
/* Open the current token to use as a base for the restricted one */
8058
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &origToken))
8159
{
8260
pg_log_error("could not open process token: error code %lu",
8361
GetLastError());
84-
FreeLibrary(Advapi32Handle);
8562
return 0;
8663
}
8764

@@ -97,22 +74,20 @@ CreateRestrictedProcess(char *cmd, PROCESS_INFORMATION *processInfo)
9774
pg_log_error("could not allocate SIDs: error code %lu",
9875
GetLastError());
9976
CloseHandle(origToken);
100-
FreeLibrary(Advapi32Handle);
10177
return 0;
10278
}
10379

104-
b = _CreateRestrictedToken(origToken,
105-
DISABLE_MAX_PRIVILEGE,
106-
sizeof(dropSids) / sizeof(dropSids[0]),
107-
dropSids,
108-
0, NULL,
109-
0, NULL,
110-
&restrictedToken);
80+
b = CreateRestrictedToken(origToken,
81+
DISABLE_MAX_PRIVILEGE,
82+
sizeof(dropSids) / sizeof(dropSids[0]),
83+
dropSids,
84+
0, NULL,
85+
0, NULL,
86+
&restrictedToken);
11187

11288
FreeSid(dropSids[1].Sid);
11389
FreeSid(dropSids[0].Sid);
11490
CloseHandle(origToken);
115-
FreeLibrary(Advapi32Handle);
11691

11792
if (!b)
11893
{

0 commit comments

Comments
 (0)