diff options
author | Tom Lane | 2005-03-25 00:35:20 +0000 |
---|---|---|
committer | Tom Lane | 2005-03-25 00:35:20 +0000 |
commit | 65181c4d602eb0f596c3828118c1ffb4bca092f4 (patch) | |
tree | 1dd2ee6cfe9fe3e88b9a48e9d23f19f07824b20e | |
parent | 2b174c0919b27bfea3185b93df80532d4ba63b61 (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-x | configure | 121 | ||||
-rw-r--r-- | configure.in | 17 | ||||
-rw-r--r-- | src/backend/postmaster/pgstat.c | 4 | ||||
-rw-r--r-- | src/backend/postmaster/postmaster.c | 8 | ||||
-rw-r--r-- | src/include/port.h | 3 | ||||
-rw-r--r-- | src/interfaces/libpq/Makefile | 2 | ||||
-rw-r--r-- | src/interfaces/libpq/fe-auth.c | 19 | ||||
-rw-r--r-- | src/interfaces/libpq/fe-connect.c | 2 | ||||
-rw-r--r-- | src/port/noblock.c | 25 |
9 files changed, 174 insertions, 27 deletions
@@ -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 +} |