summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane2005-03-25 00:35:20 +0000
committerTom Lane2005-03-25 00:35:20 +0000
commit65181c4d602eb0f596c3828118c1ffb4bca092f4 (patch)
tree1dd2ee6cfe9fe3e88b9a48e9d23f19f07824b20e
parent2b174c0919b27bfea3185b93df80532d4ba63b61 (diff)
Kerberos fixes from Magnus Hagander --- in theory Kerberos 5 auth
should work on Windows now. Also, rename set_noblock to pg_set_noblock; since it is included in libpq, the former name polluted application namespace.
-rwxr-xr-xconfigure121
-rw-r--r--configure.in17
-rw-r--r--src/backend/postmaster/pgstat.c4
-rw-r--r--src/backend/postmaster/postmaster.c8
-rw-r--r--src/include/port.h3
-rw-r--r--src/interfaces/libpq/Makefile2
-rw-r--r--src/interfaces/libpq/fe-auth.c19
-rw-r--r--src/interfaces/libpq/fe-connect.c2
-rw-r--r--src/port/noblock.c25
9 files changed, 174 insertions, 27 deletions
diff --git a/configure b/configure
index 22a2ca9a62..b77ec52aa8 100755
--- a/configure
+++ b/configure
@@ -6358,7 +6358,8 @@ done
fi
if test "$with_krb5" = yes ; then
- echo "$as_me:$LINENO: checking for library containing com_err" >&5
+ if test "$PORTNAME" != "win32"; then
+ echo "$as_me:$LINENO: checking for library containing com_err" >&5
echo $ECHO_N "checking for library containing com_err... $ECHO_C" >&6
if test "${ac_cv_search_com_err+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
@@ -6470,7 +6471,7 @@ echo "$as_me: error: could not find function 'com_err' required for Kerberos 5"
{ (exit 1); exit 1; }; }
fi
- echo "$as_me:$LINENO: checking for library containing krb5_encrypt" >&5
+ echo "$as_me:$LINENO: checking for library containing krb5_encrypt" >&5
echo $ECHO_N "checking for library containing krb5_encrypt... $ECHO_C" >&6
if test "${ac_cv_search_krb5_encrypt+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
@@ -6582,7 +6583,7 @@ echo "$as_me: error: could not find function 'krb5_encrypt' required for Kerbero
{ (exit 1); exit 1; }; }
fi
- echo "$as_me:$LINENO: checking for library containing krb5_sendauth" >&5
+ echo "$as_me:$LINENO: checking for library containing krb5_sendauth" >&5
echo $ECHO_N "checking for library containing krb5_sendauth... $ECHO_C" >&6
if test "${ac_cv_search_krb5_sendauth+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
@@ -6694,6 +6695,120 @@ echo "$as_me: error: could not find function 'krb5_sendauth' required for Kerber
{ (exit 1); exit 1; }; }
fi
+ else
+ echo "$as_me:$LINENO: checking for library containing com_err" >&5
+echo $ECHO_N "checking for library containing com_err... $ECHO_C" >&6
+if test "${ac_cv_search_com_err+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_func_search_save_LIBS=$LIBS
+ac_cv_search_com_err=no
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+#include "confdefs.h"
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char com_err ();
+#ifdef F77_DUMMY_MAIN
+# ifdef __cplusplus
+ extern "C"
+# endif
+ int F77_DUMMY_MAIN() { return 1; }
+#endif
+int
+main ()
+{
+com_err ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_search_com_err="none required"
+else
+ echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+if test "$ac_cv_search_com_err" = no; then
+ for ac_lib in 'comerr32 -lkrb5_32'; do
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+#include "confdefs.h"
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char com_err ();
+#ifdef F77_DUMMY_MAIN
+# ifdef __cplusplus
+ extern "C"
+# endif
+ int F77_DUMMY_MAIN() { return 1; }
+#endif
+int
+main ()
+{
+com_err ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_search_com_err="-l$ac_lib"
+break
+else
+ echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+ done
+fi
+LIBS=$ac_func_search_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_search_com_err" >&5
+echo "${ECHO_T}$ac_cv_search_com_err" >&6
+if test "$ac_cv_search_com_err" != no; then
+ test "$ac_cv_search_com_err" = "none required" || LIBS="$ac_cv_search_com_err $LIBS"
+
+else
+ { { echo "$as_me:$LINENO: error: could not find function 'com_err' required for Kerberos 5" >&5
+echo "$as_me: error: could not find function 'com_err' required for Kerberos 5" >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+ fi
fi
if test "$with_openssl" = yes ; then
diff --git a/configure.in b/configure.in
index 2ee08d3dd2..b0904ebc8f 100644
--- a/configure.in
+++ b/configure.in
@@ -673,12 +673,17 @@ if test "$with_krb4" = yes ; then
fi
if test "$with_krb5" = yes ; then
- AC_SEARCH_LIBS(com_err, [krb5 'krb5 -ldes -lasn1 -lroken' com_err], [],
- [AC_MSG_ERROR([could not find function 'com_err' required for Kerberos 5])])
- AC_SEARCH_LIBS(krb5_encrypt, [krb5 'krb5 -ldes -lasn1 -lroken' crypto k5crypto], [],
- [AC_MSG_ERROR([could not find function 'krb5_encrypt' required for Kerberos 5])])
- AC_SEARCH_LIBS(krb5_sendauth, [krb5 'krb5 -ldes -lasn1 -lroken'], [],
- [AC_MSG_ERROR([could not find function 'krb5_sendauth' required for Kerberos 5])])
+ if test "$PORTNAME" != "win32"; then
+ AC_SEARCH_LIBS(com_err, [krb5 'krb5 -ldes -lasn1 -lroken' com_err], [],
+ [AC_MSG_ERROR([could not find function 'com_err' required for Kerberos 5])])
+ AC_SEARCH_LIBS(krb5_encrypt, [krb5 'krb5 -ldes -lasn1 -lroken' crypto k5crypto], [],
+ [AC_MSG_ERROR([could not find function 'krb5_encrypt' required for Kerberos 5])])
+ AC_SEARCH_LIBS(krb5_sendauth, [krb5 'krb5 -ldes -lasn1 -lroken'], [],
+ [AC_MSG_ERROR([could not find function 'krb5_sendauth' required for Kerberos 5])])
+ else
+ AC_SEARCH_LIBS(com_err, 'comerr32 -lkrb5_32', [],
+ [AC_MSG_ERROR([could not find function 'com_err' required for Kerberos 5])])
+ fi
fi
if test "$with_openssl" = yes ; then
diff --git a/src/backend/postmaster/pgstat.c b/src/backend/postmaster/pgstat.c
index 14f7ef2189..4d4fd7e252 100644
--- a/src/backend/postmaster/pgstat.c
+++ b/src/backend/postmaster/pgstat.c
@@ -422,7 +422,7 @@ pgstat_init(void)
* messages will be discarded; backends won't block waiting to send
* messages to the collector.
*/
- if (!set_noblock(pgStatSock))
+ if (!pg_set_noblock(pgStatSock))
{
ereport(LOG,
(errcode_for_socket_access(),
@@ -1766,7 +1766,7 @@ pgstat_recvbuffer(void)
* Set the write pipe to nonblock mode, so that we cannot block when
* the collector falls behind.
*/
- if (!set_noblock(writePipe))
+ if (!pg_set_noblock(writePipe))
ereport(ERROR,
(errcode_for_socket_access(),
errmsg("could not set statistics collector pipe to nonblocking mode: %m")));
diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index 44bf385c3d..1df3c5c583 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -1246,10 +1246,10 @@ ServerLoop(void)
PgStatPID = pgstat_start();
/*
- * Touch the socket and lock file at least every hour, to
+ * Touch the socket and lock file every 58 minutes, to
* ensure that they are not removed by overzealous /tmp-cleaning
- * tasks. Set to 58 minutes so a cleaner never sees the
- * file as an hour old.
+ * tasks. We assume no one runs cleaners with cutoff times of
+ * less than an hour ...
*/
now = time(NULL);
if (now - last_touch_time >= 58 * 60)
@@ -2479,7 +2479,7 @@ report_fork_failure_to_client(Port *port, int errnum)
strerror(errnum));
/* Set port to non-blocking. Don't do send() if this fails */
- if (!set_noblock(port->sock))
+ if (!pg_set_noblock(port->sock))
return;
send(port->sock, buffer, strlen(buffer) + 1, 0);
diff --git a/src/include/port.h b/src/include/port.h
index acd77d4060..0613114591 100644
--- a/src/include/port.h
+++ b/src/include/port.h
@@ -20,7 +20,8 @@
#include <ctype.h>
/* non-blocking */
-extern bool set_noblock(int sock);
+extern bool pg_set_noblock(int sock);
+extern bool pg_set_block(int sock);
/* Portable path handling for Unix/Win32 */
diff --git a/src/interfaces/libpq/Makefile b/src/interfaces/libpq/Makefile
index f676188a76..483691a8ee 100644
--- a/src/interfaces/libpq/Makefile
+++ b/src/interfaces/libpq/Makefile
@@ -55,7 +55,7 @@ endif
# matter.)
SHLIB_LINK += $(filter -lcrypt -ldes -lkrb -lcom_err -lcrypto -lk5crypto -lkrb5 -lssl -lsocket -lnsl -lresolv -lintl, $(LIBS)) $(PTHREAD_LIBS)
ifeq ($(PORTNAME), win32)
-SHLIB_LINK += -lshfolder -lwsock32 -lws2_32 $(filter -leay32 -lssleay32, $(LIBS))
+SHLIB_LINK += -lshfolder -lwsock32 -lws2_32 $(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 a6dceea824..9c43cc298a 100644
--- a/src/interfaces/libpq/fe-auth.c
+++ b/src/interfaces/libpq/fe-auth.c
@@ -367,7 +367,13 @@ pg_krb5_sendauth(char *PQerrormsg, int sock, const char *hostname)
krb5_principal server;
krb5_auth_context auth_context = NULL;
krb5_error *err_ret = NULL;
- int flags;
+
+ if (!hostname)
+ {
+ snprintf(PQerrormsg, PQERRORMSG_LENGTH,
+ "pg_krb5_sendauth: hostname must be specified for Kerberos authentication\n");
+ return STATUS_ERROR;
+ }
ret = pg_krb5_init(PQerrormsg);
if (ret != STATUS_OK)
@@ -388,8 +394,7 @@ pg_krb5_sendauth(char *PQerrormsg, int sock, const char *hostname)
* socket, and we have to block somehow to do mutual authentication
* anyway. So we temporarily make it blocking.
*/
- flags = fcntl(sock, F_GETFL);
- if (flags < 0 || fcntl(sock, F_SETFL, (long) (flags & ~O_NONBLOCK)))
+ if (!pg_set_block(sock))
{
char sebuf[256];
@@ -436,7 +441,7 @@ pg_krb5_sendauth(char *PQerrormsg, int sock, const char *hostname)
krb5_free_principal(pg_krb5_context, server);
- if (fcntl(sock, F_SETFL, (long) flags))
+ if (!pg_set_noblock(sock))
{
char sebuf[256];
@@ -599,8 +604,7 @@ fe_sendauth(AuthRequest areq, PGconn *conn, const char *hostname,
(struct sockaddr_in *) & conn->raddr.addr,
hostname) != STATUS_OK)
{
- snprintf(PQerrormsg, PQERRORMSG_LENGTH,
- libpq_gettext("Kerberos 4 authentication failed\n"));
+ /* PQerrormsg already filled in */
pgunlock_thread();
return STATUS_ERROR;
}
@@ -618,8 +622,7 @@ fe_sendauth(AuthRequest areq, PGconn *conn, const char *hostname,
if (pg_krb5_sendauth(PQerrormsg, conn->sock,
hostname) != STATUS_OK)
{
- snprintf(PQerrormsg, PQERRORMSG_LENGTH,
- libpq_gettext("Kerberos 5 authentication failed\n"));
+ /* PQerrormsg already filled in */
pgunlock_thread();
return STATUS_ERROR;
}
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index e99e0c3079..6e546e75a1 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -1211,7 +1211,7 @@ keep_going: /* We will come back to here until there
continue;
}
}
- if (!set_noblock(conn->sock))
+ if (!pg_set_noblock(conn->sock))
{
printfPQExpBuffer(&conn->errorMessage,
libpq_gettext("could not set socket to non-blocking mode: %s\n"),
diff --git a/src/port/noblock.c b/src/port/noblock.c
index aa8872707b..f51079b287 100644
--- a/src/port/noblock.c
+++ b/src/port/noblock.c
@@ -18,7 +18,7 @@
#include <fcntl.h>
bool
-set_noblock(int sock)
+pg_set_noblock(int sock)
{
#if !defined(WIN32) && !defined(__BEOS__)
return (fcntl(sock, F_SETFL, O_NONBLOCK) != -1);
@@ -34,3 +34,26 @@ set_noblock(int sock)
#endif
#endif
}
+
+
+bool
+pg_set_block(int sock)
+{
+#if !defined(WIN32) && !defined(__BEOS__)
+ int flags;
+ flags = fcntl(sock, F_GETFL);
+ if (flags < 0 || fcntl(sock, F_SETFL, (long) (flags & ~O_NONBLOCK)))
+ return false;
+ return true;
+#else
+ long ioctlsocket_ret = 0;
+
+ /* Returns non-0 on failure, while fcntl() returns -1 on failure */
+#ifdef WIN32
+ return (ioctlsocket(sock, FIONBIO, &ioctlsocket_ret) == 0);
+#endif
+#ifdef __BEOS__
+ return (ioctl(sock, FIONBIO, &ioctlsocket_ret) == 0);
+#endif
+#endif
+}