Remove support for native krb5 authentication

krb5 has been deprecated since 8.3, and the recommended way to do
Kerberos authentication is using the GSSAPI authentication method
(which is still fully supported).

libpq retains the ability to identify krb5 authentication, but only
gives an error message about it being unsupported. Since all authentication
is initiated from the backend, there is no need to keep it at all
in the backend.
This commit is contained in:
Magnus Hagander 2014-01-15 17:24:01 +01:00
parent 4b8f2859cc
commit 98de86e422
22 changed files with 94 additions and 1145 deletions

314
configure vendored
View File

@ -817,7 +817,6 @@ with_tclconfig
with_perl
with_python
with_gssapi
with_krb5
with_krb_srvnam
with_pam
with_ldap
@ -1502,8 +1501,7 @@ Optional Packages:
--with-perl build Perl modules (PL/Perl)
--with-python build Python modules (PL/Python)
--with-gssapi build with GSSAPI support
--with-krb5 build with Kerberos 5 support
--with-krb-srvnam=NAME default service principal name in Kerberos
--with-krb-srvnam=NAME default service principal name in Kerberos (GSSAPI)
[postgres]
--with-pam build with PAM support
--with-ldap build with LDAP support
@ -5336,43 +5334,6 @@ fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_gssapi" >&5
$as_echo "$with_gssapi" >&6; }
#
# Kerberos 5
#
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build with Kerberos 5 support" >&5
$as_echo_n "checking whether to build with Kerberos 5 support... " >&6; }
# Check whether --with-krb5 was given.
if test "${with_krb5+set}" = set; then :
withval=$with_krb5;
case $withval in
yes)
$as_echo "#define KRB5 1" >>confdefs.h
krb_srvtab="FILE:\$(sysconfdir)/krb5.keytab"
;;
no)
:
;;
*)
as_fn_error $? "no argument expected for --with-krb5 option" "$LINENO" 5
;;
esac
else
with_krb5=no
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_krb5" >&5
$as_echo "$with_krb5" >&6; }
@ -8395,186 +8356,6 @@ fi
fi
fi
if test "$with_krb5" = yes ; then
if test "$PORTNAME" != "win32"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing com_err" >&5
$as_echo_n "checking for library containing com_err... " >&6; }
if ${ac_cv_search_com_err+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_func_search_save_LIBS=$LIBS
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
/* Override any GCC internal prototype to avoid an error.
Use char because int might match the return type of a GCC
builtin and then its argument prototype would still apply. */
#ifdef __cplusplus
extern "C"
#endif
char com_err ();
int
main ()
{
return com_err ();
;
return 0;
}
_ACEOF
for ac_lib in '' krb5 'krb5 -lcrypto -ldes -lasn1 -lroken' com_err 'com_err -lssl -lcrypto'; do
if test -z "$ac_lib"; then
ac_res="none required"
else
ac_res=-l$ac_lib
LIBS="-l$ac_lib $ac_func_search_save_LIBS"
fi
if ac_fn_c_try_link "$LINENO"; then :
ac_cv_search_com_err=$ac_res
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext
if ${ac_cv_search_com_err+:} false; then :
break
fi
done
if ${ac_cv_search_com_err+:} false; then :
else
ac_cv_search_com_err=no
fi
rm conftest.$ac_ext
LIBS=$ac_func_search_save_LIBS
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_com_err" >&5
$as_echo "$ac_cv_search_com_err" >&6; }
ac_res=$ac_cv_search_com_err
if test "$ac_res" != no; then :
test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
else
as_fn_error $? "could not find function 'com_err' required for Kerberos 5" "$LINENO" 5
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing krb5_sendauth" >&5
$as_echo_n "checking for library containing krb5_sendauth... " >&6; }
if ${ac_cv_search_krb5_sendauth+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_func_search_save_LIBS=$LIBS
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
/* Override any GCC internal prototype to avoid an error.
Use char because int might match the return type of a GCC
builtin and then its argument prototype would still apply. */
#ifdef __cplusplus
extern "C"
#endif
char krb5_sendauth ();
int
main ()
{
return krb5_sendauth ();
;
return 0;
}
_ACEOF
for ac_lib in '' krb5 'krb5 -lcrypto -ldes -lasn1 -lroken'; do
if test -z "$ac_lib"; then
ac_res="none required"
else
ac_res=-l$ac_lib
LIBS="-l$ac_lib $ac_func_search_save_LIBS"
fi
if ac_fn_c_try_link "$LINENO"; then :
ac_cv_search_krb5_sendauth=$ac_res
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext
if ${ac_cv_search_krb5_sendauth+:} false; then :
break
fi
done
if ${ac_cv_search_krb5_sendauth+:} false; then :
else
ac_cv_search_krb5_sendauth=no
fi
rm conftest.$ac_ext
LIBS=$ac_func_search_save_LIBS
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_krb5_sendauth" >&5
$as_echo "$ac_cv_search_krb5_sendauth" >&6; }
ac_res=$ac_cv_search_krb5_sendauth
if test "$ac_res" != no; then :
test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
else
as_fn_error $? "could not find function 'krb5_sendauth' required for Kerberos 5" "$LINENO" 5
fi
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing com_err" >&5
$as_echo_n "checking for library containing com_err... " >&6; }
if ${ac_cv_search_com_err+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_func_search_save_LIBS=$LIBS
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
/* Override any GCC internal prototype to avoid an error.
Use char because int might match the return type of a GCC
builtin and then its argument prototype would still apply. */
#ifdef __cplusplus
extern "C"
#endif
char com_err ();
int
main ()
{
return com_err ();
;
return 0;
}
_ACEOF
for ac_lib in '' 'comerr32 -lkrb5_32'; do
if test -z "$ac_lib"; then
ac_res="none required"
else
ac_res=-l$ac_lib
LIBS="-l$ac_lib $ac_func_search_save_LIBS"
fi
if ac_fn_c_try_link "$LINENO"; then :
ac_cv_search_com_err=$ac_res
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext
if ${ac_cv_search_com_err+:} false; then :
break
fi
done
if ${ac_cv_search_com_err+:} false; then :
else
ac_cv_search_com_err=no
fi
rm conftest.$ac_ext
LIBS=$ac_func_search_save_LIBS
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_com_err" >&5
$as_echo "$ac_cv_search_com_err" >&6; }
ac_res=$ac_cv_search_com_err
if test "$ac_res" != no; then :
test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
else
as_fn_error $? "could not find function 'com_err' required for Kerberos 5" "$LINENO" 5
fi
fi
fi
if test "$with_openssl" = yes ; then
if test "$PORTNAME" != "win32"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for CRYPTO_new_ex_data in -lcrypto" >&5
@ -9494,17 +9275,6 @@ fi
done
fi
if test "$with_krb5" = yes ; then
ac_fn_c_check_header_mongrel "$LINENO" "krb5.h" "ac_cv_header_krb5_h" "$ac_includes_default"
if test "x$ac_cv_header_krb5_h" = xyes; then :
else
as_fn_error $? "header file <krb5.h> is required for Kerberos 5" "$LINENO" 5
fi
fi
if test "$with_openssl" = yes ; then
@ -10772,88 +10542,6 @@ fi
fi
if test "$with_krb5" = yes; then
# Check for differences between MIT and Heimdal (KTH) releases
ac_fn_c_check_member "$LINENO" "krb5_ticket" "enc_part2" "ac_cv_member_krb5_ticket_enc_part2" "#include <krb5.h>
"
if test "x$ac_cv_member_krb5_ticket_enc_part2" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_KRB5_TICKET_ENC_PART2 1
_ACEOF
else
ac_fn_c_check_member "$LINENO" "krb5_ticket" "client" "ac_cv_member_krb5_ticket_client" "#include <krb5.h>
"
if test "x$ac_cv_member_krb5_ticket_client" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_KRB5_TICKET_CLIENT 1
_ACEOF
else
as_fn_error $? "could not determine how to get client name from Kerberos 5 ticket" "$LINENO" 5
fi
fi
ac_fn_c_check_member "$LINENO" "krb5_error" "text.data" "ac_cv_member_krb5_error_text_data" "#include <krb5.h>
"
if test "x$ac_cv_member_krb5_error_text_data" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_KRB5_ERROR_TEXT_DATA 1
_ACEOF
else
ac_fn_c_check_member "$LINENO" "krb5_error" "e_data" "ac_cv_member_krb5_error_e_data" "#include <krb5.h>
"
if test "x$ac_cv_member_krb5_error_e_data" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_KRB5_ERROR_E_DATA 1
_ACEOF
else
as_fn_error $? "could not determine how to extract Kerberos 5 error messages" "$LINENO" 5
fi
fi
# Win32 requires headers to be loaded for __stdcall, so can't use
# AC_CHECK_FUNCS here.
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for krb5_free_unparsed_name" >&5
$as_echo_n "checking for krb5_free_unparsed_name... " >&6; }
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <krb5.h>
int
main ()
{
krb5_free_unparsed_name(NULL,NULL);
;
return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
$as_echo "#define HAVE_KRB5_FREE_UNPARSED_NAME 1" >>confdefs.h
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
fi
# On PPC, check if assembler supports LWARX instruction's mutex hint bit
case $host_cpu in
ppc*|powerpc*)

View File

@ -608,17 +608,6 @@ PGAC_ARG_BOOL(with, gssapi, no, [build with GSSAPI support],
])
AC_MSG_RESULT([$with_gssapi])
#
# Kerberos 5
#
AC_MSG_CHECKING([whether to build with Kerberos 5 support])
PGAC_ARG_BOOL(with, krb5, no, [build with Kerberos 5 support],
[
AC_DEFINE(KRB5, 1, [Define to build with Kerberos 5 support. (--with-krb5)])
krb_srvtab="FILE:\$(sysconfdir)/krb5.keytab"
])
AC_MSG_RESULT([$with_krb5])
AC_SUBST(krb_srvtab)
@ -627,11 +616,11 @@ AC_SUBST(krb_srvtab)
# Kerberos configuration parameters
#
PGAC_ARG_REQ(with, krb-srvnam,
[NAME], [default service principal name in Kerberos [postgres]],
[NAME], [default service principal name in Kerberos (GSSAPI) [postgres]],
[],
[with_krb_srvnam="postgres"])
AC_DEFINE_UNQUOTED([PG_KRB_SRVNAM], ["$with_krb_srvnam"],
[Define to the name of the default PostgreSQL service principal in Kerberos. (--with-krb-srvnam=NAME)])
[Define to the name of the default PostgreSQL service principal in Kerberos (GSSAPI). (--with-krb-srvnam=NAME)])
#
@ -929,18 +918,6 @@ if test "$with_gssapi" = yes ; then
fi
fi
if test "$with_krb5" = yes ; then
if test "$PORTNAME" != "win32"; then
AC_SEARCH_LIBS(com_err, [krb5 'krb5 -lcrypto -ldes -lasn1 -lroken' com_err 'com_err -lssl -lcrypto'], [],
[AC_MSG_ERROR([could not find function 'com_err' required for Kerberos 5])])
AC_SEARCH_LIBS(krb5_sendauth, [krb5 'krb5 -lcrypto -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
dnl Order matters!
if test "$PORTNAME" != "win32"; then
@ -1061,10 +1038,6 @@ if test "$with_gssapi" = yes ; then
[AC_CHECK_HEADERS(gssapi.h, [], [AC_MSG_ERROR([gssapi.h header file is required for GSSAPI])])])
fi
if test "$with_krb5" = yes ; then
AC_CHECK_HEADER(krb5.h, [], [AC_MSG_ERROR([header file <krb5.h> is required for Kerberos 5])])
fi
if test "$with_openssl" = yes ; then
AC_CHECK_HEADER(openssl/ssl.h, [], [AC_MSG_ERROR([header file <openssl/ssl.h> is required for OpenSSL])])
AC_CHECK_HEADER(openssl/err.h, [], [AC_MSG_ERROR([header file <openssl/err.h> is required for OpenSSL])])
@ -1160,29 +1133,6 @@ Use --without-zlib to disable zlib support.])],
[#include <zlib.h>])
fi
if test "$with_krb5" = yes; then
# Check for differences between MIT and Heimdal (KTH) releases
AC_CHECK_MEMBERS(krb5_ticket.enc_part2, [],
[AC_CHECK_MEMBERS(krb5_ticket.client, [],
[AC_MSG_ERROR([could not determine how to get client name from Kerberos 5 ticket])],
[#include <krb5.h>])],
[#include <krb5.h>])
AC_CHECK_MEMBERS(krb5_error.text.data, [],
[AC_CHECK_MEMBERS(krb5_error.e_data, [],
[AC_MSG_ERROR([could not determine how to extract Kerberos 5 error messages])],
[#include <krb5.h>])],
[#include <krb5.h>])
# Win32 requires headers to be loaded for __stdcall, so can't use
# AC_CHECK_FUNCS here.
AC_MSG_CHECKING(for krb5_free_unparsed_name)
AC_TRY_LINK([#include <krb5.h>],
[krb5_free_unparsed_name(NULL,NULL);],
[AC_DEFINE(HAVE_KRB5_FREE_UNPARSED_NAME, 1, [Define to 1 if you have krb5_free_unparsed_name.])
AC_MSG_RESULT(yes)],
[AC_MSG_RESULT(no)])
fi
# On PPC, check if assembler supports LWARX instruction's mutex hint bit
case $host_cpu in
ppc*|powerpc*)

View File

@ -450,17 +450,6 @@ hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>krb5</></term>
<listitem>
<para>
Use Kerberos V5 to authenticate the user. This is only
available for TCP/IP connections. See <xref
linkend="kerberos-auth"> for details.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>ident</></term>
<listitem>
@ -650,13 +639,13 @@ host all all .example.com md5
# In the absence of preceding "host" lines, these two lines will
# reject all connections from 192.168.54.1 (since that entry will be
# matched first), but allow Kerberos 5 connections from anywhere else
# matched first), but allow GSSAPI connections from anywhere else
# on the Internet. The zero mask causes no bits of the host IP
# address to be considered, so it matches any host.
#
# TYPE DATABASE USER ADDRESS METHOD
host all all 192.168.54.1/32 reject
host all all 0.0.0.0/0 krb5
host all all 0.0.0.0/0 gss
# Allow users from 192.168.x.x hosts to connect to any database, if
# they pass the ident check. If, for example, ident says the user is
@ -925,16 +914,74 @@ omicron bryanh guest1
</para>
<para>
When <productname>GSSAPI</productname> uses
<productname>Kerberos</productname>, it uses a standard principal
in the format
<literal><replaceable>servicename</>/<replaceable>hostname</>@<replaceable>realm</></literal>. For information about the parts of the principal, and
how to set up the required keys, see <xref linkend="kerberos-auth">.
GSSAPI support has to be enabled when <productname>PostgreSQL</> is built;
see <xref linkend="installation"> for more information.
</para>
<para>
GSSAPI support has to be enabled when <productname>PostgreSQL</> is built;
see <xref linkend="installation"> for more information.
When <productname>GSSAPI</productname> uses
<productname>Kerberos</productname>, it uses a standard principal
in the format
<literal><replaceable>servicename</>/<replaceable>hostname</>@<replaceable>realm</></literal>.
<replaceable>servicename</> can be set on the server side using the
<xref linkend="guc-krb-srvname"> configuration parameter, and on the
client side using the <literal>krbsrvname</> connection parameter. (See
also <xref linkend="libpq-paramkeywords">.) The installation default can be
changed from the default <literal>postgres</literal> at build time using
<literal>./configure --with-krb-srvnam=</><replaceable>whatever</>.
In most environments,
this parameter never needs to be changed. However, it is necessary
when supporting multiple <productname>PostgreSQL</> installations
on the same host.
Some Kerberos implementations might also require a different service name,
such as Microsoft Active Directory which requires the service name
to be in upper case (<literal>POSTGRES</literal>).
</para>
<para>
<replaceable>hostname</> is the fully qualified host name of the
server machine. The service principal's realm is the preferred realm
of the server machine.
</para>
<para>
Client principals must have their <productname>PostgreSQL</> database user
name as their first component, for example
<literal>pgusername@realm</>. Alternatively, you can use a user name
mapping to map from the first component of the principal name to the
database user name. By default, the realm of the client is
not checked by <productname>PostgreSQL</>. If you have cross-realm
authentication enabled and need to verify the realm, use the
<literal>krb_realm</> parameter, or enable <literal>include_realm</>
and use user name mapping to check the realm.
</para>
<para>
Make sure that your server keytab file is readable (and preferably
only readable) by the <productname>PostgreSQL</productname> server
account. (See also <xref linkend="postgres-user">.) The location
of the key file is specified by the <xref
linkend="guc-krb-server-keyfile"> configuration
parameter. The default is
<filename>/usr/local/pgsql/etc/krb5.keytab</> (or whatever
directory was specified as <varname>sysconfdir</> at build time).
</para>
<para>
The keytab file is generated by the Kerberos software; see the
Kerberos documentation for details. The following example is
for MIT-compatible Kerberos 5 implementations:
<screen>
<prompt>kadmin% </><userinput>ank -randkey postgres/server.my.domain.org</>
<prompt>kadmin% </><userinput>ktadd -k krb5.keytab postgres/server.my.domain.org</>
</screen>
</para>
<para>
When connecting to the database make sure you have a ticket for a
principal matching the requested database user name. For example, for
database user name <literal>fred</>, principal
<literal>fred@EXAMPLE.COM</> would be able to connect. To also allow
principal <literal>fred/users.example.com@EXAMPLE.COM</>, use a user name
map, as described in <xref linkend="auth-username-maps">.
</para>
<para>
@ -1050,178 +1097,6 @@ omicron bryanh guest1
</para>
</sect2>
<sect2 id="kerberos-auth">
<title>Kerberos Authentication</title>
<indexterm zone="kerberos-auth">
<primary>Kerberos</primary>
</indexterm>
<note>
<para>
Native Kerberos authentication has been deprecated and should be used
only for backward compatibility. New and upgraded installations are
encouraged to use the industry-standard <productname>GSSAPI</productname>
authentication method (see <xref linkend="gssapi-auth">) instead.
</para>
</note>
<para>
<productname>Kerberos</productname> is an industry-standard secure
authentication system suitable for distributed computing over a public
network. A description of the <productname>Kerberos</productname> system
is beyond the scope of this document; in full generality it can be
quite complex (yet powerful). The
<ulink url="http://www.cmf.nrl.navy.mil/CCS/people/kenh/kerberos-faq.html">
Kerberos <acronym>FAQ</></ulink> or
<ulink url="http://web.mit.edu/kerberos/www/">MIT Kerberos page</ulink>
can be good starting points for exploration.
Several sources for <productname>Kerberos</> distributions exist.
<productname>Kerberos</productname> provides secure authentication but
does not encrypt queries or data passed over the network; for that
use <acronym>SSL</acronym>.
</para>
<para>
<productname>PostgreSQL</> supports Kerberos version 5. Kerberos
support has to be enabled when <productname>PostgreSQL</> is built;
see <xref linkend="installation"> for more information.
</para>
<para>
<productname>PostgreSQL</> operates like a normal Kerberos service.
The name of the service principal is
<literal><replaceable>servicename</>/<replaceable>hostname</>@<replaceable>realm</></literal>.
</para>
<para>
<replaceable>servicename</> can be set on the server side using the
<xref linkend="guc-krb-srvname"> configuration parameter, and on the
client side using the <literal>krbsrvname</> connection parameter. (See
also <xref linkend="libpq-paramkeywords">.) The installation default can be
changed from the default <literal>postgres</literal> at build time using
<literal>./configure --with-krb-srvnam=</><replaceable>whatever</>.
In most environments,
this parameter never needs to be changed. However, it is necessary
when supporting multiple <productname>PostgreSQL</> installations
on the same host.
Some Kerberos implementations might also require a different service name,
such as Microsoft Active Directory which requires the service name
to be in upper case (<literal>POSTGRES</literal>).
</para>
<para>
<replaceable>hostname</> is the fully qualified host name of the
server machine. The service principal's realm is the preferred realm
of the server machine.
</para>
<para>
Client principals must have their <productname>PostgreSQL</> database user
name as their first component, for example
<literal>pgusername@realm</>. Alternatively, you can use a user name
mapping to map from the first component of the principal name to the
database user name. By default, the realm of the client is
not checked by <productname>PostgreSQL</>. If you have cross-realm
authentication enabled and need to verify the realm, use the
<literal>krb_realm</> parameter, or enable <literal>include_realm</>
and use user name mapping to check the realm.
</para>
<para>
Make sure that your server keytab file is readable (and preferably
only readable) by the <productname>PostgreSQL</productname> server
account. (See also <xref linkend="postgres-user">.) The location
of the key file is specified by the <xref
linkend="guc-krb-server-keyfile"> configuration
parameter. The default is
<filename>/usr/local/pgsql/etc/krb5.keytab</> (or whatever
directory was specified as <varname>sysconfdir</> at build time).
</para>
<para>
The keytab file is generated by the Kerberos software; see the
Kerberos documentation for details. The following example is
for MIT-compatible Kerberos 5 implementations:
<screen>
<prompt>kadmin% </><userinput>ank -randkey postgres/server.my.domain.org</>
<prompt>kadmin% </><userinput>ktadd -k krb5.keytab postgres/server.my.domain.org</>
</screen>
</para>
<para>
When connecting to the database make sure you have a ticket for a
principal matching the requested database user name. For example, for
database user name <literal>fred</>, principal
<literal>fred@EXAMPLE.COM</> would be able to connect. To also allow
principal <literal>fred/users.example.com@EXAMPLE.COM</>, use a user name
map, as described in <xref linkend="auth-username-maps">.
</para>
<para>
If you use <ulink url="http://modauthkerb.sf.net">
<application>mod_auth_kerb</application></ulink>
and <application>mod_perl</application> on your
<productname>Apache</productname> web server, you can use
<literal>AuthType KerberosV5SaveCredentials</literal> with a
<application>mod_perl</application> script. This gives secure
database access over the web, with no additional passwords required.
</para>
<para>
The following configuration options are supported for
<productname>Kerberos</productname>:
<variablelist>
<varlistentry>
<term><literal>map</literal></term>
<listitem>
<para>
Allows for mapping between system and database user names. See
<xref linkend="auth-username-maps"> for details.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>include_realm</literal></term>
<listitem>
<para>
If set to 1, the realm name from the authenticated user
principal is included in the system user name that's passed through
user name mapping (<xref linkend="auth-username-maps">). This is
useful for handling users from multiple realms.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>krb_realm</literal></term>
<listitem>
<para>
Sets the realm to match user principal names against. If this parameter
is set, only users of that realm will be accepted. If it is not set,
users of any realm can connect, subject to whatever user name mapping
is done.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>krb_server_hostname</literal></term>
<listitem>
<para>
Sets the host name part of the service principal.
This, combined with <varname>krb_srvname</>, is used to generate
the complete service principal, that is
<varname>krb_srvname</><literal>/</><varname>krb_server_hostname</><literal>@</>REALM.
If not set, the default is the server host name.
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
</sect2>
<sect2 id="auth-ident">
<title>Ident Authentication</title>

View File

@ -964,7 +964,7 @@ include 'filename'
<listitem>
<para>
Sets the location of the Kerberos server key file. See
<xref linkend="kerberos-auth"> or <xref linkend="gssapi-auth">
<xref linkend="gssapi-auth">
for details. This parameter can only be set in the
<filename>postgresql.conf</> file or on the server command line.
</para>
@ -978,7 +978,7 @@ include 'filename'
</indexterm>
<listitem>
<para>
Sets the Kerberos service name. See <xref linkend="kerberos-auth">
Sets the Kerberos service name. See <xref linkend="gssapi-auth">
for details. This parameter can only be set in the
<filename>postgresql.conf</> file or on the server command line.
</para>
@ -992,7 +992,7 @@ include 'filename'
</indexterm>
<listitem>
<para>
Sets whether Kerberos and GSSAPI user names should be treated
Sets whether GSSAPI user names should be treated
case-insensitively.
The default is <literal>off</> (case sensitive). This parameter can only be
set in the <filename>postgresql.conf</> file or on the server command line.

View File

@ -269,7 +269,7 @@ $ENV{PATH}=$ENV{PATH} . ';c:\some\where\bison\bin';
<varlistentry>
<term><productname>MIT Kerberos</productname></term>
<listitem><para>
Required for Kerberos authentication support. MIT Kerberos can be
Required for GSSAPI authentication support. MIT Kerberos can be
downloaded from
<ulink url="http://web.mit.edu/Kerberos/dist/index.html"></>.
</para></listitem>

View File

@ -771,28 +771,12 @@ su - postgres
</listitem>
</varlistentry>
<varlistentry>
<term><option>--with-krb5</option></term>
<listitem>
<para>
Build with support for Kerberos 5 authentication. On many
systems, the Kerberos system is not installed in a location
that is searched by default (e.g., <filename>/usr/include</>,
<filename>/usr/lib</>), so you must use the options
<option>--with-includes</> and <option>--with-libraries</> in
addition to this option. <filename>configure</> will check
for the required header files and libraries to make sure that
your Kerberos installation is sufficient before proceeding.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>--with-krb-srvnam=<replaceable>NAME</></option></term>
<listitem>
<para>
The default name of the Kerberos service principal (also used
by GSSAPI).
The default name of the Kerberos service principal used
by GSSAPI.
<literal>postgres</literal> is the default. There's usually no
reason to change this unless you have a Windows environment,
in which case it must be set to upper case

View File

@ -896,7 +896,7 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname
Using <literal>hostaddr</> instead of <literal>host</> allows the
application to avoid a host name look-up, which might be important
in applications with time constraints. However, a host name is
required for Kerberos, GSSAPI, or SSPI authentication
required for GSSAPI or SSPI authentication
methods, as well as for <literal>verify-full</> SSL
certificate verification. The following rules are used:
<itemizedlist>
@ -1331,11 +1331,10 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname
<term><literal>krbsrvname</literal></term>
<listitem>
<para>
Kerberos service name to use when authenticating with Kerberos 5
or GSSAPI.
Kerberos service name to use when authenticating with GSSAPI.
This must match the service name specified in the server
configuration for Kerberos authentication to succeed. (See also
<xref linkend="kerberos-auth"> and <xref linkend="gssapi-auth">.)
<xref linkend="gssapi-auth">.)
</para>
</listitem>
</varlistentry>
@ -6652,7 +6651,7 @@ myEventProc(PGEventId evtId, void *evtInfo, void *passThrough)
<application>libpq</application> applications will attempt
authentication with servers for this realm and use separate ticket
files to avoid conflicts with local ticket files. This
environment variable is only used if Kerberos authentication is
environment variable is only used if GSSAPI authentication is
selected by the server.
</para>
</listitem>

View File

@ -48,7 +48,7 @@
module, because in that case it can only try to guess the password.
For this reason, <filename>passwordcheck</filename> is not
recommended if your security requirements are high.
It is more secure to use an external authentication method such as Kerberos
It is more secure to use an external authentication method such as GSSAPI
(see <xref linkend="client-authentication">) than to rely on
passwords within the database.
</para>

View File

@ -271,7 +271,8 @@
authentication dialog (not described here, part of the
Kerberos specification) with the server. If this is
successful, the server responds with an AuthenticationOk,
otherwise it responds with an ErrorResponse.
otherwise it responds with an ErrorResponse. This is no
longer supported. This is not supported any more.
</para>
</listitem>
</varlistentry>

View File

@ -133,29 +133,6 @@ char *pg_krb_srvnam;
bool pg_krb_caseins_users;
/*----------------------------------------------------------------
* MIT Kerberos authentication system - protocol version 5
*----------------------------------------------------------------
*/
#ifdef KRB5
static int pg_krb5_recvauth(Port *port);
#include <krb5.h>
/* Some old versions of Kerberos do not include <com_err.h> in <krb5.h> */
#if !defined(__COM_ERR_H) && !defined(__COM_ERR_H__)
#include <com_err.h>
#endif
/*
* Various krb5 state which is not connection specific, and a flag to
* indicate whether we have initialised it yet.
*/
static int pg_krb5_initialised;
static krb5_context pg_krb5_context;
static krb5_keytab pg_krb5_keytab;
static krb5_principal pg_krb5_server;
#endif /* KRB5 */
/*----------------------------------------------------------------
* GSSAPI Authentication
*----------------------------------------------------------------
@ -257,9 +234,6 @@ auth_failed(Port *port, int status)
case uaImplicitReject:
errstr = gettext_noop("authentication failed for user \"%s\": host rejected");
break;
case uaKrb5:
errstr = gettext_noop("Kerberos 5 authentication failed for user \"%s\"");
break;
case uaTrust:
errstr = gettext_noop("\"trust\" authentication failed for user \"%s\"");
break;
@ -497,15 +471,6 @@ ClientAuthentication(Port *port)
break;
}
case uaKrb5:
#ifdef KRB5
sendAuthRequest(port, AUTH_REQ_KRB5);
status = pg_krb5_recvauth(port);
#else
Assert(false);
#endif
break;
case uaGSS:
#ifdef ENABLE_GSS
sendAuthRequest(port, AUTH_REQ_GSS);
@ -735,188 +700,6 @@ recv_and_check_password_packet(Port *port)
}
/*----------------------------------------------------------------
* MIT Kerberos authentication system - protocol version 5
*----------------------------------------------------------------
*/
#ifdef KRB5
static int
pg_krb5_init(Port *port)
{
krb5_error_code retval;
char *khostname;
if (pg_krb5_initialised)
return STATUS_OK;
retval = krb5_init_context(&pg_krb5_context);
if (retval)
{
ereport(LOG,
(errmsg("Kerberos initialization returned error %d",
retval)));
com_err("postgres", retval, "while initializing krb5");
return STATUS_ERROR;
}
retval = krb5_kt_resolve(pg_krb5_context, pg_krb_server_keyfile, &pg_krb5_keytab);
if (retval)
{
ereport(LOG,
(errmsg("Kerberos keytab resolving returned error %d",
retval)));
com_err("postgres", retval, "while resolving keytab file \"%s\"",
pg_krb_server_keyfile);
krb5_free_context(pg_krb5_context);
return STATUS_ERROR;
}
/*
* If no hostname was specified, pg_krb_server_hostname is already NULL.
* If it's set to blank, force it to NULL.
*/
khostname = port->hba->krb_server_hostname;
if (khostname && khostname[0] == '\0')
khostname = NULL;
retval = krb5_sname_to_principal(pg_krb5_context,
khostname,
pg_krb_srvnam,
KRB5_NT_SRV_HST,
&pg_krb5_server);
if (retval)
{
ereport(LOG,
(errmsg("Kerberos sname_to_principal(\"%s\", \"%s\") returned error %d",
khostname ? khostname : "server hostname", pg_krb_srvnam, retval)));
com_err("postgres", retval,
"while getting server principal for server \"%s\" for service \"%s\"",
khostname ? khostname : "server hostname", pg_krb_srvnam);
krb5_kt_close(pg_krb5_context, pg_krb5_keytab);
krb5_free_context(pg_krb5_context);
return STATUS_ERROR;
}
pg_krb5_initialised = 1;
return STATUS_OK;
}
/*
* pg_krb5_recvauth -- server routine to receive authentication information
* from the client
*
* We still need to compare the username obtained from the client's setup
* packet to the authenticated name.
*
* We have our own keytab file because postgres is unlikely to run as root,
* and so cannot read the default keytab.
*/
static int
pg_krb5_recvauth(Port *port)
{
krb5_error_code retval;
int ret;
krb5_auth_context auth_context = NULL;
krb5_ticket *ticket;
char *kusername;
char *cp;
ret = pg_krb5_init(port);
if (ret != STATUS_OK)
return ret;
retval = krb5_recvauth(pg_krb5_context, &auth_context,
(krb5_pointer) & port->sock, pg_krb_srvnam,
pg_krb5_server, 0, pg_krb5_keytab, &ticket);
if (retval)
{
ereport(LOG,
(errmsg("Kerberos recvauth returned error %d",
retval)));
com_err("postgres", retval, "from krb5_recvauth");
return STATUS_ERROR;
}
/*
* The "client" structure comes out of the ticket and is therefore
* authenticated. Use it to check the username obtained from the
* postmaster startup packet.
*/
#if defined(HAVE_KRB5_TICKET_ENC_PART2)
retval = krb5_unparse_name(pg_krb5_context,
ticket->enc_part2->client, &kusername);
#elif defined(HAVE_KRB5_TICKET_CLIENT)
retval = krb5_unparse_name(pg_krb5_context,
ticket->client, &kusername);
#else
#error "bogus configuration"
#endif
if (retval)
{
ereport(LOG,
(errmsg("Kerberos unparse_name returned error %d",
retval)));
com_err("postgres", retval, "while unparsing client name");
krb5_free_ticket(pg_krb5_context, ticket);
krb5_auth_con_free(pg_krb5_context, auth_context);
return STATUS_ERROR;
}
cp = strchr(kusername, '@');
if (cp)
{
/*
* If we are not going to include the realm in the username that is
* passed to the ident map, destructively modify it here to remove the
* realm. Then advance past the separator to check the realm.
*/
if (!port->hba->include_realm)
*cp = '\0';
cp++;
if (port->hba->krb_realm != NULL && strlen(port->hba->krb_realm))
{
/* Match realm against configured */
if (pg_krb_caseins_users)
ret = pg_strcasecmp(port->hba->krb_realm, cp);
else
ret = strcmp(port->hba->krb_realm, cp);
if (ret)
{
elog(DEBUG2,
"krb5 realm (%s) and configured realm (%s) don't match",
cp, port->hba->krb_realm);
krb5_free_ticket(pg_krb5_context, ticket);
krb5_auth_con_free(pg_krb5_context, auth_context);
return STATUS_ERROR;
}
}
}
else if (port->hba->krb_realm && strlen(port->hba->krb_realm))
{
elog(DEBUG2,
"krb5 did not return realm but realm matching was requested");
krb5_free_ticket(pg_krb5_context, ticket);
krb5_auth_con_free(pg_krb5_context, auth_context);
return STATUS_ERROR;
}
ret = check_usermap(port->hba->usermap, port->user_name, kusername,
pg_krb_caseins_users);
krb5_free_ticket(pg_krb5_context, ticket);
krb5_auth_con_free(pg_krb5_context, auth_context);
free(kusername);
return ret;
}
#endif /* KRB5 */
/*----------------------------------------------------------------
* GSSAPI authentication system

View File

@ -1177,12 +1177,6 @@ parse_hba_line(List *line, int line_num, char *raw_line)
parsedline->auth_method = uaPeer;
else if (strcmp(token->string, "password") == 0)
parsedline->auth_method = uaPassword;
else if (strcmp(token->string, "krb5") == 0)
#ifdef KRB5
parsedline->auth_method = uaKrb5;
#else
unsupauth = "krb5";
#endif
else if (strcmp(token->string, "gss") == 0)
#ifdef ENABLE_GSS
parsedline->auth_method = uaGSS;
@ -1261,17 +1255,6 @@ parse_hba_line(List *line, int line_num, char *raw_line)
parsedline->auth_method = uaPeer;
/* Invalid authentication combinations */
if (parsedline->conntype == ctLocal &&
parsedline->auth_method == uaKrb5)
{
ereport(LOG,
(errcode(ERRCODE_CONFIG_FILE_ERROR),
errmsg("krb5 authentication is not supported on local sockets"),
errcontext("line %d of configuration file \"%s\"",
line_num, HbaFileName)));
return NULL;
}
if (parsedline->conntype == ctLocal &&
parsedline->auth_method == uaGSS)
{
@ -1417,11 +1400,10 @@ parse_hba_auth_opt(char *name, char *val, HbaLine *hbaline, int line_num)
{
if (hbaline->auth_method != uaIdent &&
hbaline->auth_method != uaPeer &&
hbaline->auth_method != uaKrb5 &&
hbaline->auth_method != uaGSS &&
hbaline->auth_method != uaSSPI &&
hbaline->auth_method != uaCert)
INVALID_AUTH_OPTION("map", gettext_noop("ident, peer, krb5, gssapi, sspi, and cert"));
INVALID_AUTH_OPTION("map", gettext_noop("ident, peer, gssapi, sspi, and cert"));
hbaline->usermap = pstrdup(val);
}
else if (strcmp(name, "clientcert") == 0)
@ -1578,25 +1560,18 @@ parse_hba_auth_opt(char *name, char *val, HbaLine *hbaline, int line_num)
REQUIRE_AUTH_OPTION(uaLDAP, "ldapsuffix", "ldap");
hbaline->ldapsuffix = pstrdup(val);
}
else if (strcmp(name, "krb_server_hostname") == 0)
{
REQUIRE_AUTH_OPTION(uaKrb5, "krb_server_hostname", "krb5");
hbaline->krb_server_hostname = pstrdup(val);
}
else if (strcmp(name, "krb_realm") == 0)
{
if (hbaline->auth_method != uaKrb5 &&
hbaline->auth_method != uaGSS &&
if (hbaline->auth_method != uaGSS &&
hbaline->auth_method != uaSSPI)
INVALID_AUTH_OPTION("krb_realm", gettext_noop("krb5, gssapi, and sspi"));
INVALID_AUTH_OPTION("krb_realm", gettext_noop("gssapi and sspi"));
hbaline->krb_realm = pstrdup(val);
}
else if (strcmp(name, "include_realm") == 0)
{
if (hbaline->auth_method != uaKrb5 &&
hbaline->auth_method != uaGSS &&
if (hbaline->auth_method != uaGSS &&
hbaline->auth_method != uaSSPI)
INVALID_AUTH_OPTION("include_realm", gettext_noop("krb5, gssapi, and sspi"));
INVALID_AUTH_OPTION("include_realm", gettext_noop("gssapi and sspi"));
if (strcmp(val, "1") == 0)
hbaline->include_realm = true;
else

View File

@ -43,7 +43,7 @@
# directly connected to.
#
# METHOD can be "trust", "reject", "md5", "password", "gss", "sspi",
# "krb5", "ident", "peer", "pam", "ldap", "radius" or "cert". Note that
# "ident", "peer", "pam", "ldap", "radius" or "cert". Note that
# "password" sends passwords in clear text; "md5" is preferred since
# it sends encrypted passwords.
#

View File

@ -76,9 +76,6 @@ static const char *auth_methods_host[] = {"trust", "reject", "md5", "password",
#ifdef ENABLE_SSPI
"sspi",
#endif
#ifdef KRB5
"krb5",
#endif
#ifdef USE_PAM
"pam", "pam ",
#endif

View File

@ -20,7 +20,6 @@ typedef enum UserAuth
{
uaReject,
uaImplicitReject,
uaKrb5,
uaTrust,
uaIdent,
uaPassword,

View File

@ -164,7 +164,7 @@ extern bool Db_user_namespace;
#define AUTH_REQ_OK 0 /* User is authenticated */
#define AUTH_REQ_KRB4 1 /* Kerberos V4. Not supported any more. */
#define AUTH_REQ_KRB5 2 /* Kerberos V5 */
#define AUTH_REQ_KRB5 2 /* Kerberos V5. Not supported any more. */
#define AUTH_REQ_PASSWORD 3 /* Password */
#define AUTH_REQ_CRYPT 4 /* crypt password. Not supported any more. */
#define AUTH_REQ_MD5 5 /* md5 password */

View File

@ -260,21 +260,6 @@
/* Define to 1 if you have isinf(). */
#undef HAVE_ISINF
/* Define to 1 if `e_data' is a member of `krb5_error'. */
#undef HAVE_KRB5_ERROR_E_DATA
/* Define to 1 if `text.data' is a member of `krb5_error'. */
#undef HAVE_KRB5_ERROR_TEXT_DATA
/* Define to 1 if you have krb5_free_unparsed_name. */
#undef HAVE_KRB5_FREE_UNPARSED_NAME
/* Define to 1 if `client' is a member of `krb5_ticket'. */
#undef HAVE_KRB5_TICKET_CLIENT
/* Define to 1 if `enc_part2' is a member of `krb5_ticket'. */
#undef HAVE_KRB5_TICKET_ENC_PART2
/* Define to 1 if you have the <langinfo.h> header file. */
#undef HAVE_LANGINFO_H
@ -656,9 +641,6 @@
/* Define to the appropriate snprintf format for 64-bit ints. */
#undef INT64_FORMAT
/* Define to build with Kerberos 5 support. (--with-krb5) */
#undef KRB5
/* Define to 1 if `locale_t' requires <xlocale.h>. */
#undef LOCALE_T_IN_XLOCALE

View File

@ -193,18 +193,6 @@
/* Define to 1 if you have isinf(). */
#define HAVE_ISINF 1
/* Define to 1 if `e_data' is member of `krb5_error'. */
/* #undef HAVE_KRB5_ERROR_E_DATA */
/* Define to 1 if `text.data' is member of `krb5_error'. */
/* #undef HAVE_KRB5_ERROR_TEXT_DATA */
/* Define to 1 if `client' is member of `krb5_ticket'. */
/* #undef HAVE_KRB5_TICKET_CLIENT */
/* Define to 1 if `enc_part2' is member of `krb5_ticket'. */
/* #undef HAVE_KRB5_TICKET_ENC_PART2 */
/* Define to 1 if you have the <langinfo.h> header file. */
/* #undef HAVE_LANGINFO_H */
@ -541,9 +529,6 @@
/* Define to the appropriate snprintf format for 64-bit ints, if any. */
#define INT64_FORMAT "%lld"
/* Define to build with Kerberos 5 support. (--with-krb5) */
/* #undef KRB5 */
/* Define to 1 if `locale_t' requires <xlocale.h>. */
/* #undef LOCALE_T_IN_XLOCALE */

View File

@ -43,258 +43,6 @@
#include "libpq/md5.h"
#ifdef KRB5
/*
* MIT Kerberos authentication system - protocol version 5
*/
#include <krb5.h>
/* Some old versions of Kerberos do not include <com_err.h> in <krb5.h> */
#if !defined(__COM_ERR_H) && !defined(__COM_ERR_H__)
#include <com_err.h>
#endif
/*
* Heimdal doesn't have a free function for unparsed names. Just pass it to
* standard free() which should work in these cases.
*/
#ifndef HAVE_KRB5_FREE_UNPARSED_NAME
static void
krb5_free_unparsed_name(krb5_context context, char *val)
{
free(val);
}
#endif
/*
* pg_an_to_ln -- return the local name corresponding to an authentication
* name
*
* XXX Assumes that the first aname component is the user name. This is NOT
* necessarily so, since an aname can actually be something out of your
* worst X.400 nightmare, like
* ORGANIZATION=U. C. Berkeley/NAME=Paul M. Aoki@CS.BERKELEY.EDU
* Note that the MIT an_to_ln code does the same thing if you don't
* provide an aname mapping database...it may be a better idea to use
* krb5_an_to_ln, except that it punts if multiple components are found,
* and we can't afford to punt.
*
* For WIN32, convert username to lowercase because the Win32 kerberos library
* generates tickets with the username as the user entered it instead of as
* it is entered in the directory.
*/
static char *
pg_an_to_ln(char *aname)
{
char *p;
if ((p = strchr(aname, '/')) || (p = strchr(aname, '@')))
*p = '\0';
#ifdef WIN32
for (p = aname; *p; p++)
*p = pg_tolower((unsigned char) *p);
#endif
return aname;
}
/*
* Various krb5 state which is not connection specific, and a flag to
* indicate whether we have initialised it yet.
*/
/*
static int pg_krb5_initialised;
static krb5_context pg_krb5_context;
static krb5_ccache pg_krb5_ccache;
static krb5_principal pg_krb5_client;
static char *pg_krb5_name;
*/
struct krb5_info
{
int pg_krb5_initialised;
krb5_context pg_krb5_context;
krb5_ccache pg_krb5_ccache;
krb5_principal pg_krb5_client;
char *pg_krb5_name;
};
static int
pg_krb5_init(PQExpBuffer errorMessage, struct krb5_info * info)
{
krb5_error_code retval;
if (info->pg_krb5_initialised)
return STATUS_OK;
retval = krb5_init_context(&(info->pg_krb5_context));
if (retval)
{
printfPQExpBuffer(errorMessage,
"pg_krb5_init: krb5_init_context: %s\n",
error_message(retval));
return STATUS_ERROR;
}
retval = krb5_cc_default(info->pg_krb5_context, &(info->pg_krb5_ccache));
if (retval)
{
printfPQExpBuffer(errorMessage,
"pg_krb5_init: krb5_cc_default: %s\n",
error_message(retval));
krb5_free_context(info->pg_krb5_context);
return STATUS_ERROR;
}
retval = krb5_cc_get_principal(info->pg_krb5_context, info->pg_krb5_ccache,
&(info->pg_krb5_client));
if (retval)
{
printfPQExpBuffer(errorMessage,
"pg_krb5_init: krb5_cc_get_principal: %s\n",
error_message(retval));
krb5_cc_close(info->pg_krb5_context, info->pg_krb5_ccache);
krb5_free_context(info->pg_krb5_context);
return STATUS_ERROR;
}
retval = krb5_unparse_name(info->pg_krb5_context, info->pg_krb5_client, &(info->pg_krb5_name));
if (retval)
{
printfPQExpBuffer(errorMessage,
"pg_krb5_init: krb5_unparse_name: %s\n",
error_message(retval));
krb5_free_principal(info->pg_krb5_context, info->pg_krb5_client);
krb5_cc_close(info->pg_krb5_context, info->pg_krb5_ccache);
krb5_free_context(info->pg_krb5_context);
return STATUS_ERROR;
}
info->pg_krb5_name = pg_an_to_ln(info->pg_krb5_name);
info->pg_krb5_initialised = 1;
return STATUS_OK;
}
static void
pg_krb5_destroy(struct krb5_info * info)
{
krb5_free_principal(info->pg_krb5_context, info->pg_krb5_client);
krb5_cc_close(info->pg_krb5_context, info->pg_krb5_ccache);
krb5_free_unparsed_name(info->pg_krb5_context, info->pg_krb5_name);
krb5_free_context(info->pg_krb5_context);
}
/*
* pg_krb5_sendauth -- client routine to send authentication information to
* the server
*/
static int
pg_krb5_sendauth(PGconn *conn)
{
krb5_error_code retval;
int ret;
krb5_principal server;
krb5_auth_context auth_context = NULL;
krb5_error *err_ret = NULL;
struct krb5_info info;
info.pg_krb5_initialised = 0;
if (!(conn->pghost && conn->pghost[0] != '\0'))
{
printfPQExpBuffer(&conn->errorMessage,
libpq_gettext("host name must be specified\n"));
return STATUS_ERROR;
}
ret = pg_krb5_init(&conn->errorMessage, &info);
if (ret != STATUS_OK)
return ret;
retval = krb5_sname_to_principal(info.pg_krb5_context, conn->pghost,
conn->krbsrvname,
KRB5_NT_SRV_HST, &server);
if (retval)
{
printfPQExpBuffer(&conn->errorMessage,
"pg_krb5_sendauth: krb5_sname_to_principal: %s\n",
error_message(retval));
pg_krb5_destroy(&info);
return STATUS_ERROR;
}
/*
* libpq uses a non-blocking socket. But kerberos needs a blocking socket,
* and we have to block somehow to do mutual authentication anyway. So we
* temporarily make it blocking.
*/
if (!pg_set_block(conn->sock))
{
char sebuf[256];
printfPQExpBuffer(&conn->errorMessage,
libpq_gettext("could not set socket to blocking mode: %s\n"), pqStrerror(errno, sebuf, sizeof(sebuf)));
krb5_free_principal(info.pg_krb5_context, server);
pg_krb5_destroy(&info);
return STATUS_ERROR;
}
retval = krb5_sendauth(info.pg_krb5_context, &auth_context,
(krb5_pointer) & conn->sock, (char *) conn->krbsrvname,
info.pg_krb5_client, server,
AP_OPTS_MUTUAL_REQUIRED,
NULL, 0, /* no creds, use ccache instead */
info.pg_krb5_ccache, &err_ret, NULL, NULL);
if (retval)
{
if (retval == KRB5_SENDAUTH_REJECTED && err_ret)
{
#if defined(HAVE_KRB5_ERROR_TEXT_DATA)
printfPQExpBuffer(&conn->errorMessage,
libpq_gettext("Kerberos 5 authentication rejected: %*s\n"),
(int) err_ret->text.length, err_ret->text.data);
#elif defined(HAVE_KRB5_ERROR_E_DATA)
printfPQExpBuffer(&conn->errorMessage,
libpq_gettext("Kerberos 5 authentication rejected: %*s\n"),
(int) err_ret->e_data->length,
(const char *) err_ret->e_data->data);
#else
#error "bogus configuration"
#endif
}
else
{
printfPQExpBuffer(&conn->errorMessage,
"krb5_sendauth: %s\n", error_message(retval));
}
if (err_ret)
krb5_free_error(info.pg_krb5_context, err_ret);
ret = STATUS_ERROR;
}
krb5_free_principal(info.pg_krb5_context, server);
if (!pg_set_noblock(conn->sock))
{
char sebuf[256];
printfPQExpBuffer(&conn->errorMessage,
libpq_gettext("could not restore nonblocking mode on socket: %s\n"),
pqStrerror(errno, sebuf, sizeof(sebuf)));
ret = STATUS_ERROR;
}
pg_krb5_destroy(&info);
return ret;
}
#endif /* KRB5 */
#ifdef ENABLE_GSS
/*
* GSSAPI authentication system.
@ -816,21 +564,9 @@ pg_fe_sendauth(AuthRequest areq, PGconn *conn)
return STATUS_ERROR;
case AUTH_REQ_KRB5:
#ifdef KRB5
pglock_thread();
if (pg_krb5_sendauth(conn) != STATUS_OK)
{
/* Error message already filled in */
pgunlock_thread();
return STATUS_ERROR;
}
pgunlock_thread();
break;
#else
printfPQExpBuffer(&conn->errorMessage,
libpq_gettext("Kerberos 5 authentication not supported\n"));
return STATUS_ERROR;
#endif
#if defined(ENABLE_GSS) || defined(ENABLE_SSPI)
case AUTH_REQ_GSS:

View File

@ -278,7 +278,7 @@ static const internalPQconninfoOption PQconninfoOptions[] = {
"Require-Peer", "", 10,
offsetof(struct pg_conn, requirepeer)},
#if defined(KRB5) || defined(ENABLE_GSS) || defined(ENABLE_SSPI)
#if defined(ENABLE_GSS) || defined(ENABLE_SSPI)
/* Kerberos and GSSAPI authentication support specifying the service name */
{"krbsrvname", "PGKRBSRVNAME", PG_KRB_SRVNAM, NULL,
"Kerberos-service-name", "", 20,
@ -2823,7 +2823,7 @@ freePGconn(PGconn *conn)
free(conn->sslcompression);
if (conn->requirepeer)
free(conn->requirepeer);
#if defined(KRB5) || defined(ENABLE_GSS) || defined(ENABLE_SSPI)
#if defined(ENABLE_GSS) || defined(ENABLE_SSPI)
if (conn->krbsrvname)
free(conn->krbsrvname);
#endif

View File

@ -331,7 +331,7 @@ struct pg_conn
char *sslcrl; /* certificate revocation list filename */
char *requirepeer; /* required peer credentials for local sockets */
#if defined(KRB5) || defined(ENABLE_GSS) || defined(ENABLE_SSPI)
#if defined(ENABLE_GSS) || defined(ENABLE_SSPI)
char *krbsrvname; /* Kerberos service name */
#endif

View File

@ -221,10 +221,6 @@ s{PG_VERSION_STR "[^"]+"}{__STRINGIFY(x) #x\n#define __STRINGIFY2(z) __STRINGIFY
}
if ($self->{options}->{krb5})
{
print O "#define KRB5 1\n";
print O "#define HAVE_KRB5_ERROR_TEXT_DATA 1\n";
print O "#define HAVE_KRB5_TICKET_ENC_PART2 1\n";
print O "#define HAVE_KRB5_FREE_UNPARSED_NAME 1\n";
print O "#define ENABLE_GSS 1\n";
}
if (my $port = $self->{options}->{"--with-pgport"})
@ -625,7 +621,7 @@ sub GetFakeConfigure
$cfg .= ' --with-ossp-uuid' if ($self->{options}->{uuid});
$cfg .= ' --with-libxml' if ($self->{options}->{xml});
$cfg .= ' --with-libxslt' if ($self->{options}->{xslt});
$cfg .= ' --with-krb5' if ($self->{options}->{krb5});
$cfg .= ' --with-gssapi' if ($self->{options}->{krb5});
$cfg .= ' --with-tcl' if ($self->{options}->{tcl});
$cfg .= ' --with-perl' if ($self->{options}->{perl});
$cfg .= ' --with-python' if ($self->{options}->{python});

View File

@ -15,7 +15,6 @@ our $config = {
tcl => undef, # --with-tls=<path>
perl => undef, # --with-perl
python => undef, # --with-python=<path>
krb5 => undef, # --with-krb5=<path>
openssl => undef, # --with-ssl=<path>
uuid => undef, # --with-ossp-uuid
xml => undef, # --with-libxml=<path>