From d60259249428809cad22e2de152544de60c7ee81 Mon Sep 17 00:00:00 2001
From: Magnus Hagander <magnus@hagander.net>
Date: Tue, 24 Jul 2007 09:00:27 +0000
Subject: [PATCH] Make it possible, and default, for MingW to build with SSPI
 support by dynamically loading the function that's missing from the MingW
 headers and library.

---
 src/backend/Makefile           |  3 ++-
 src/backend/libpq/auth.c       | 37 ++++++++++++++++++++++++++++++----
 src/include/port/win32.h       |  9 ++++++++-
 src/interfaces/libpq/Makefile  |  4 ++--
 src/interfaces/libpq/fe-auth.c | 11 ++++++----
 src/tools/msvc/Solution.pm     |  3 +--
 6 files changed, 53 insertions(+), 14 deletions(-)

diff --git a/src/backend/Makefile b/src/backend/Makefile
index 2082bf294eb..d2caa7036ce 100644
--- a/src/backend/Makefile
+++ b/src/backend/Makefile
@@ -4,7 +4,7 @@
 #
 # Copyright (c) 1994, Regents of the University of California
 #
-# $PostgreSQL: pgsql/src/backend/Makefile,v 1.122 2007/02/09 15:55:57 petere Exp $
+# $PostgreSQL: pgsql/src/backend/Makefile,v 1.123 2007/07/24 09:00:27 mha Exp $
 #
 #-------------------------------------------------------------------------
 
@@ -64,6 +64,7 @@ libpostgres.a: postgres.def
 endif # cygwin
 
 ifeq ($(PORTNAME), win32)
+LIBS += -lsecur32
 
 postgres: $(OBJS) postgres.def libpostgres.a $(WIN32RES)
 	$(DLLTOOL) --dllname $@$(X) --output-exp $@.exp --def postgres.def
diff --git a/src/backend/libpq/auth.c b/src/backend/libpq/auth.c
index c475c6429d6..d3bb35f40ff 100644
--- a/src/backend/libpq/auth.c
+++ b/src/backend/libpq/auth.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/libpq/auth.c,v 1.154 2007/07/23 10:16:53 mha Exp $
+ *	  $PostgreSQL: pgsql/src/backend/libpq/auth.c,v 1.155 2007/07/24 09:00:27 mha Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -560,13 +560,16 @@ pg_SSPI_error(int severity, char *errmsg, SECURITY_STATUS r)
 	if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, r, 0, sysmsg, sizeof(sysmsg), NULL) == 0)
 		ereport(severity,
 		        (errmsg_internal("%s", errmsg),
-				errdetail("sspi error %x", r)));
+				errdetail("sspi error %x", (unsigned int)r)));
 	else
 		ereport(severity,
 		        (errmsg_internal("%s", errmsg),
-				errdetail("%s (%x)", sysmsg, r)));
+				errdetail("%s (%x)", sysmsg, (unsigned int)r)));
 }
 
+typedef SECURITY_STATUS
+(WINAPI * QUERY_SECURITY_CONTEXT_TOKEN_FN)(
+    PCtxtHandle, void **);
 
 static int
 pg_SSPI_recvauth(Port *port)
@@ -591,6 +594,8 @@ pg_SSPI_recvauth(Port *port)
 	DWORD			accountnamesize = sizeof(accountname);
 	DWORD			domainnamesize = sizeof(domainname);
 	SID_NAME_USE	accountnameuse;
+	HMODULE			secur32;
+	QUERY_SECURITY_CONTEXT_TOKEN_FN	_QuerySecurityContextToken;
 
 
 	/*
@@ -726,12 +731,36 @@ pg_SSPI_recvauth(Port *port)
 	 *
 	 * Get the name of the user that authenticated, and compare it to the
 	 * pg username that was specified for the connection.
+	 *
+	 * MingW is missing the export for QuerySecurityContextToken in
+	 * the secur32 library, so we have to load it dynamically.
 	 */
 
-	r = QuerySecurityContextToken(sspictx, &token);
+	secur32 = LoadLibrary("SECUR32.DLL");
+	if (secur32 == NULL)
+		ereport(ERROR,
+			(errmsg_internal("could not load secur32.dll: %d",
+			(int)GetLastError())));
+
+	_QuerySecurityContextToken = (QUERY_SECURITY_CONTEXT_TOKEN_FN)
+		GetProcAddress(secur32, "QuerySecurityContextToken");
+	if (_QuerySecurityContextToken == NULL)
+	{
+		FreeLibrary(secur32);
+		ereport(ERROR,
+			(errmsg_internal("could not locate QuerySecurityContextToken in secur32.dll: %d",
+			(int)GetLastError())));
+	}
+
+	r = (_QuerySecurityContextToken)(sspictx, &token);
 	if (r != SEC_E_OK)
+	{
+		FreeLibrary(secur32);
 		pg_SSPI_error(ERROR,
 			gettext_noop("could not get security token from context"), r);
+	}
+
+	FreeLibrary(secur32);
 
 	/*
 	 * No longer need the security context, everything from here on uses the
diff --git a/src/include/port/win32.h b/src/include/port/win32.h
index fcf995ef8c0..e05ab50ca77 100644
--- a/src/include/port/win32.h
+++ b/src/include/port/win32.h
@@ -1,9 +1,16 @@
-/* $PostgreSQL: pgsql/src/include/port/win32.h,v 1.74 2007/04/06 05:36:51 tgl Exp $ */
+/* $PostgreSQL: pgsql/src/include/port/win32.h,v 1.75 2007/07/24 09:00:27 mha Exp $ */
 
 #if defined(_MSC_VER) || defined(__BORLANDC__)
 #define WIN32_ONLY_COMPILER
 #endif
 
+/*
+ * Always build with SSPI support. Keep it as a #define in case 
+ * we want a switch to disable it sometime in the future.
+ */
+#define ENABLE_SSPI 1
+
+
 /* undefine and redefine after #include */
 #undef mkdir
 
diff --git a/src/interfaces/libpq/Makefile b/src/interfaces/libpq/Makefile
index 7d5ede01cc7..2ca8e9aa34e 100644
--- a/src/interfaces/libpq/Makefile
+++ b/src/interfaces/libpq/Makefile
@@ -5,7 +5,7 @@
 # Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
 # Portions Copyright (c) 1994, Regents of the University of California
 #
-# $PostgreSQL: pgsql/src/interfaces/libpq/Makefile,v 1.155 2007/07/10 13:14:21 mha Exp $
+# $PostgreSQL: pgsql/src/interfaces/libpq/Makefile,v 1.156 2007/07/24 09:00:27 mha Exp $
 #
 #-------------------------------------------------------------------------
 
@@ -62,7 +62,7 @@ else
 SHLIB_LINK += $(filter -lcrypt -ldes -lcom_err -lcrypto -lk5crypto -lkrb5 -lgssapi32 -lssl -lsocket -lnsl -lresolv -lintl $(PTHREAD_LIBS), $(LIBS)) $(LDAP_LIBS_FE)
 endif
 ifeq ($(PORTNAME), win32)
-SHLIB_LINK += -lshfolder -lwsock32 -lws2_32 $(filter -leay32 -lssleay32 -lcomerr32 -lkrb5_32, $(LIBS))
+SHLIB_LINK += -lshfolder -lwsock32 -lws2_32 -lsecur32 $(filter -leay32 -lssleay32 -lcomerr32 -lkrb5_32, $(LIBS))
 endif
 
 
diff --git a/src/interfaces/libpq/fe-auth.c b/src/interfaces/libpq/fe-auth.c
index 227eac7cc2b..43a183df394 100644
--- a/src/interfaces/libpq/fe-auth.c
+++ b/src/interfaces/libpq/fe-auth.c
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/interfaces/libpq/fe-auth.c,v 1.130 2007/07/23 17:52:06 mha Exp $
+ *	  $PostgreSQL: pgsql/src/interfaces/libpq/fe-auth.c,v 1.131 2007/07/24 09:00:27 mha Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -511,10 +511,13 @@ pg_SSPI_error(PGconn *conn, char *mprefix, SECURITY_STATUS r)
 {
 	char sysmsg[256];
 
-	if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, r, 0, sysmsg, sizeof(sysmsg), NULL) == 0)
-		printfPQExpBuffer(&conn->errorMessage, "%s: sspi error %x", mprefix, r);
+	if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, r, 0,
+					  sysmsg, sizeof(sysmsg), NULL) == 0)
+		printfPQExpBuffer(&conn->errorMessage, "%s: sspi error %x",
+						  mprefix, (unsigned int)r);
 	else
-		printfPQExpBuffer(&conn->errorMessage, "%s: %s (%x)", mprefix, sysmsg, r);
+		printfPQExpBuffer(&conn->errorMessage, "%s: %s (%x)",
+						  mprefix, sysmsg, (unsigned int)r);
 }
 
 /* 
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index 3a5d4df655b..39d9193e4bc 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -3,7 +3,7 @@ package Solution;
 #
 # Package that encapsulates a Visual C++ solution file generation
 #
-# $PostgreSQL: pgsql/src/tools/msvc/Solution.pm,v 1.30 2007/07/23 10:16:54 mha Exp $
+# $PostgreSQL: pgsql/src/tools/msvc/Solution.pm,v 1.31 2007/07/24 09:00:27 mha Exp $
 #
 use Carp;
 use strict;
@@ -126,7 +126,6 @@ s{PG_VERSION_STR "[^"]+"}{__STRINGIFY(x) #x\n#define __STRINGIFY2(z) __STRINGIFY
             print O "#define HAVE_KRB5_FREE_UNPARSED_NAME 1\n";
             print O "#define ENABLE_GSS 1\n";
         }
-        print O "#define ENABLE_SSPI 1\n";
         if (my $port = $self->{options}->{"--with-pgport"})
         {
             print O "#undef DEF_PGPORT\n";
-- 
GitLab