Make it possible, and default, for MingW to build with SSPI support
authorMagnus Hagander <magnus@hagander.net>
Tue, 24 Jul 2007 09:00:27 +0000 (09:00 +0000)
committerMagnus Hagander <magnus@hagander.net>
Tue, 24 Jul 2007 09:00:27 +0000 (09:00 +0000)
by dynamically loading the function that's missing from the MingW
headers and library.

src/backend/Makefile
src/backend/libpq/auth.c
src/include/port/win32.h
src/interfaces/libpq/Makefile
src/interfaces/libpq/fe-auth.c
src/tools/msvc/Solution.pm

index a48a19092e913f896df2986c07e99eb89d3aa6cc..2ae965ccc88d080e637a5e200260b6925878f81d 100644 (file)
@@ -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
index 71612e9808501c2793c862dba2287e5acdfb10d2..8ac97c1b95314d8afbcd24b0e344dd243daa6759 100644 (file)
@@ -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
index ef79f6da4f56b910b2d2ffdccd668e17d79f0607..9e77183f54180b65cd1f37115aed99d26a03c786 100644 (file)
@@ -4,6 +4,13 @@
 #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
 
index de3e797fd285bc78491fc14480f4598e8895d994..448b00b12d6043d95d6ba8b71bc707c8247411ed 100644 (file)
@@ -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
 
 
index 815328630a34c41ea9c18fc09446b1d2c247d153..620078a410e221098d3fd4a1893afe635984a1d7 100644 (file)
@@ -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);
 }
 
 /* 
index 52386486e85b16d1b22a7a8bd8ed710c5cf1c0e7..9e7f5f126caad812b628bb3db687bb1d0f347988 100644 (file)
@@ -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";