aboutsummaryrefslogtreecommitdiff
path: root/src/backend/port/win32
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/port/win32')
-rw-r--r--src/backend/port/win32/Makefile4
-rw-r--r--src/backend/port/win32/security.c184
-rw-r--r--src/backend/port/win32/signal.c15
3 files changed, 194 insertions, 9 deletions
diff --git a/src/backend/port/win32/Makefile b/src/backend/port/win32/Makefile
index 0d5b64ce364..8069d590fd4 100644
--- a/src/backend/port/win32/Makefile
+++ b/src/backend/port/win32/Makefile
@@ -4,7 +4,7 @@
# Makefile for port/win32
#
# IDENTIFICATION
-# $PostgreSQL: pgsql/src/backend/port/win32/Makefile,v 1.4 2004/04/12 16:19:18 momjian Exp $
+# $PostgreSQL: pgsql/src/backend/port/win32/Makefile,v 1.5 2004/06/24 21:02:42 tgl Exp $
#
#-------------------------------------------------------------------------
@@ -12,7 +12,7 @@ subdir = src/backend/port/win32
top_builddir = ../../../..
include $(top_builddir)/src/Makefile.global
-OBJS = sema.o shmem.o timer.o socket.o signal.o
+OBJS = sema.o shmem.o timer.o socket.o signal.o security.o
all: SUBSYS.o
diff --git a/src/backend/port/win32/security.c b/src/backend/port/win32/security.c
new file mode 100644
index 00000000000..acc2f41343c
--- /dev/null
+++ b/src/backend/port/win32/security.c
@@ -0,0 +1,184 @@
+/*-------------------------------------------------------------------------
+ *
+ * security.c
+ * Microsoft Windows Win32 Security Support Functions
+ *
+ * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
+ *
+ * IDENTIFICATION
+ * $PostgreSQL: pgsql/src/backend/port/win32/security.c,v 1.1 2004/06/24 21:02:42 tgl Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#include "postgres.h"
+
+
+/*
+ * Returns nonzero if the current user has administrative privileges,
+ * or zero if not.
+ *
+ * Note: this cannot use ereport() because it's called too early during
+ * startup.
+ */
+int
+pgwin32_is_admin(void)
+{
+ HANDLE AccessToken;
+ UCHAR InfoBuffer[1024];
+ PTOKEN_GROUPS Groups = (PTOKEN_GROUPS)InfoBuffer;
+ DWORD InfoBufferSize;
+ PSID AdministratorsSid;
+ PSID PowerUsersSid;
+ SID_IDENTIFIER_AUTHORITY NtAuthority = { SECURITY_NT_AUTHORITY };
+ UINT x;
+ BOOL success;
+
+ if(!OpenProcessToken(GetCurrentProcess(),TOKEN_READ,&AccessToken))
+ {
+ write_stderr("failed to open process token: %d\n",
+ (int)GetLastError());
+ exit(1);
+ }
+
+ if (!GetTokenInformation(AccessToken,TokenGroups,InfoBuffer,
+ 1024, &InfoBufferSize))
+ {
+ write_stderr("failed to get token information: %d\n",
+ (int)GetLastError());
+ exit(1);
+ }
+
+ CloseHandle(AccessToken);
+
+ if(!AllocateAndInitializeSid(&NtAuthority, 2,
+ SECURITY_BUILTIN_DOMAIN_RID,DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0,
+ 0,&AdministratorsSid))
+ {
+ write_stderr("failed to get SID for Administrators group: %d\n",
+ (int)GetLastError());
+ exit(1);
+ }
+
+ if (!AllocateAndInitializeSid(&NtAuthority, 2,
+ SECURITY_BUILTIN_DOMAIN_RID,DOMAIN_ALIAS_RID_POWER_USERS, 0, 0, 0, 0, 0,
+ 0, &PowerUsersSid))
+ {
+ write_stderr("failed to get SID for PowerUsers group: %d\n",
+ (int)GetLastError());
+ exit(1);
+ }
+
+ success = FALSE;
+
+ for (x=0; x<Groups->GroupCount; x++)
+ {
+ if (EqualSid(AdministratorsSid, Groups->Groups[x].Sid) ||
+ EqualSid(PowerUsersSid, Groups->Groups[x].Sid))
+ {
+ success = TRUE;
+ break;
+ }
+ }
+
+ FreeSid(AdministratorsSid);
+ FreeSid(PowerUsersSid);
+ return success;
+}
+
+/*
+ * We consider ourselves running as a service if one of the following is
+ * true:
+ *
+ * 1) We are running as Local System (only used by services)
+ * 2) Our token contains SECURITY_SERVICE_RID (automatically added to the
+ * process token by the SCM when starting a service)
+ *
+ * Return values:
+ * 0 = Not service
+ * 1 = Service
+ * -1 = Error
+ *
+ * Note: we can't report errors via either ereport (we're called too early)
+ * or write_stderr (because that calls this). We are therefore reduced to
+ * writing directly on stderr, which sucks, but we have few alternatives.
+ */
+int
+pgwin32_is_service(void)
+{
+ static int _is_service = -1;
+ HANDLE AccessToken;
+ UCHAR InfoBuffer[1024];
+ PTOKEN_GROUPS Groups = (PTOKEN_GROUPS)InfoBuffer;
+ PTOKEN_USER User = (PTOKEN_USER)InfoBuffer;
+ DWORD InfoBufferSize;
+ PSID ServiceSid;
+ PSID LocalSystemSid;
+ SID_IDENTIFIER_AUTHORITY NtAuthority = { SECURITY_NT_AUTHORITY };
+ UINT x;
+
+ /* Only check the first time */
+ if (_is_service != -1)
+ return _is_service;
+
+ if (!OpenProcessToken(GetCurrentProcess(),TOKEN_READ,&AccessToken)) {
+ fprintf(stderr,"failed to open process token: %d\n",
+ (int)GetLastError());
+ return -1;
+ }
+
+ /* First check for local system */
+ if (!GetTokenInformation(AccessToken,TokenUser,InfoBuffer,1024,&InfoBufferSize)) {
+ fprintf(stderr,"failed to get token information: %d\n",
+ (int)GetLastError());
+ return -1;
+ }
+
+ if (!AllocateAndInitializeSid(&NtAuthority,1,
+ SECURITY_LOCAL_SYSTEM_RID,0,0,0,0,0,0,0,
+ &LocalSystemSid)) {
+ fprintf(stderr,"failed to get SID for local system account\n");
+ CloseHandle(AccessToken);
+ return -1;
+ }
+
+ if (EqualSid(LocalSystemSid, User->User.Sid)) {
+ FreeSid(LocalSystemSid);
+ CloseHandle(AccessToken);
+ _is_service = 1;
+ return _is_service;
+ }
+
+ FreeSid(LocalSystemSid);
+
+ /* Now check for group SID */
+ if (!GetTokenInformation(AccessToken,TokenGroups,InfoBuffer,1024,&InfoBufferSize)) {
+ fprintf(stderr,"failed to get token information: %d\n",
+ (int)GetLastError());
+ return -1;
+ }
+
+ if (!AllocateAndInitializeSid(&NtAuthority,1,
+ SECURITY_SERVICE_RID, 0, 0, 0, 0, 0, 0, 0,
+ &ServiceSid)) {
+ fprintf(stderr,"failed to get SID for service group\n");
+ CloseHandle(AccessToken);
+ return -1;
+ }
+
+ _is_service = 0;
+ for (x = 0; x < Groups->GroupCount; x++)
+ {
+ if (EqualSid(ServiceSid, Groups->Groups[x].Sid))
+ {
+ _is_service = 1;
+ break;
+ }
+ }
+
+ FreeSid(ServiceSid);
+
+ CloseHandle(AccessToken);
+
+ return _is_service;
+}
diff --git a/src/backend/port/win32/signal.c b/src/backend/port/win32/signal.c
index fc0652a5b01..a5cc2561123 100644
--- a/src/backend/port/win32/signal.c
+++ b/src/backend/port/win32/signal.c
@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/port/win32/signal.c,v 1.3 2004/05/27 14:39:29 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/port/win32/signal.c,v 1.4 2004/06/24 21:02:42 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -63,18 +63,18 @@ pgwin32_signal_initialize(void)
pgwin32_signal_event = CreateEvent(NULL, TRUE, FALSE, NULL);
if (pgwin32_signal_event == NULL)
ereport(FATAL,
- (errmsg_internal("Failed to create signal event: %i!",(int)GetLastError())));
+ (errmsg_internal("failed to create signal event: %d", (int)GetLastError())));
/* Create thread for handling signals */
signal_thread_handle = CreateThread(NULL, 0, pg_signal_thread, NULL, 0, NULL);
if (signal_thread_handle == NULL)
ereport(FATAL,
- (errmsg_internal("Failed to create signal handler thread!")));
+ (errmsg_internal("failed to create signal handler thread")));
/* Create console control handle to pick up Ctrl-C etc */
if (!SetConsoleCtrlHandler(pg_console_handler, TRUE))
ereport(FATAL,
- (errmsg_internal("Failed to set console control handler!")));
+ (errmsg_internal("failed to set console control handler")));
}
@@ -209,7 +209,7 @@ pg_signal_thread(LPVOID param)
char pipename[128];
HANDLE pipe = INVALID_HANDLE_VALUE;
- wsprintf(pipename, "\\\\.\\pipe\\pgsignal_%i", GetCurrentProcessId());
+ wsprintf(pipename, "\\\\.\\pipe\\pgsignal_%d", GetCurrentProcessId());
for (;;)
{
@@ -221,7 +221,7 @@ pg_signal_thread(LPVOID param)
PIPE_UNLIMITED_INSTANCES, 16, 16, 1000, NULL);
if (pipe == INVALID_HANDLE_VALUE)
{
- fprintf(stderr, gettext("Failed to create signal listener pipe: %i. Retrying.\n"), (int) GetLastError());
+ write_stderr("failed to create signal listener pipe: %d. Retrying.\n", (int) GetLastError());
SleepEx(500, FALSE);
continue;
}
@@ -233,7 +233,8 @@ pg_signal_thread(LPVOID param)
(LPTHREAD_START_ROUTINE) pg_signal_dispatch_thread,
(LPVOID) pipe, 0, NULL);
if (hThread == INVALID_HANDLE_VALUE)
- fprintf(stderr, gettext("Failed to create signal dispatch thread: %i\n"), (int) GetLastError());
+ write_stderr("failed to create signal dispatch thread: %d\n",
+ (int) GetLastError());
else
CloseHandle(hThread);
}