summaryrefslogtreecommitdiff
path: root/src/port/win32security.c
diff options
context:
space:
mode:
authorAndres Freund <andres@anarazel.de>2021-09-07 11:56:13 -0700
committerAndres Freund <andres@anarazel.de>2021-09-07 11:56:13 -0700
commit76e38b37a5f179d4c9d2865ff31b79130407530b (patch)
treef9a1c893952550fcf4aa8e612ecd5569a87f3c92 /src/port/win32security.c
parent6ac763f19a6556c43933c5252065a5c81cde094d (diff)
windows: Only consider us to be running as service if stderr is invalid.
Previously pgwin32_is_service() would falsely return true when postgres is started from somewhere within a service, but not as a service. That is e.g. always the case with windows docker containers, which some CI services use to run windows tests in. When postgres falsely thinks its running as a service, no messages are writting to stdout / stderr. That can be very confusing and causes a few tests to fail. To fix additionally check if stderr is invalid in pgwin32_is_service(). For that to work in backend processes, pg_ctl is changed to pass down handles so that postgres can do the same check (otherwise "default" handles are created). While this problem exists in all branches, there have been no reports by users, the prospective CI usage currently is only for master, and I am not a windows expert. So doing the change in only master for now seems the sanest approach. Author: Andres Freund <andres@anarazel.de> Reviewed-By: Magnus Hagander <magnus@hagander.net> Discussion: https://postgr.es/m/20210305185752.3up5eq2eanb7ofmb@alap3.anarazel.de
Diffstat (limited to 'src/port/win32security.c')
-rw-r--r--src/port/win32security.c18
1 files changed, 15 insertions, 3 deletions
diff --git a/src/port/win32security.c b/src/port/win32security.c
index 4a673fde19a..6a1bd9b8654 100644
--- a/src/port/win32security.c
+++ b/src/port/win32security.c
@@ -95,8 +95,11 @@ pgwin32_is_admin(void)
* We consider ourselves running as a service if one of the following is
* true:
*
- * 1) We are running as LocalSystem (only used by services)
- * 2) Our token contains SECURITY_SERVICE_RID (automatically added to the
+ * 1) Standard error is not valid (always the case for services, and pg_ctl
+ * running as a service "passes" that down to postgres,
+ * c.f. CreateRestrictedProcess())
+ * 2) We are running as LocalSystem (only used by services)
+ * 3) Our token contains SECURITY_SERVICE_RID (automatically added to the
* process token by the SCM when starting a service)
*
* The check for LocalSystem is needed, because surprisingly, if a service
@@ -121,12 +124,21 @@ pgwin32_is_service(void)
PSID ServiceSid;
PSID LocalSystemSid;
SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY};
+ HANDLE stderr_handle;
/* Only check the first time */
if (_is_service != -1)
return _is_service;
- /* First check for LocalSystem */
+ /* Check if standard error is not valid */
+ stderr_handle = GetStdHandle(STD_ERROR_HANDLE);
+ if (stderr_handle != INVALID_HANDLE_VALUE && stderr_handle != NULL)
+ {
+ _is_service = 0;
+ return _is_service;
+ }
+
+ /* Check if running as LocalSystem */
if (!AllocateAndInitializeSid(&NtAuthority, 1,
SECURITY_LOCAL_SYSTEM_RID, 0, 0, 0, 0, 0, 0, 0,
&LocalSystemSid))