Commit 34c33a1f authored by Tom Lane's avatar Tom Lane

Add BSD authentication method.

Create a "bsd" auth method that works the same as "password" so far as
clients are concerned, but calls the BSD Authentication service to
check the password.  This is currently only available on OpenBSD.

Marisa Emerson, reviewed by Thomas Munro
parent af025eed
...@@ -827,6 +827,7 @@ with_python ...@@ -827,6 +827,7 @@ with_python
with_gssapi with_gssapi
with_krb_srvnam with_krb_srvnam
with_pam with_pam
with_bsd_auth
with_ldap with_ldap
with_bonjour with_bonjour
with_openssl with_openssl
...@@ -1516,6 +1517,7 @@ Optional Packages: ...@@ -1516,6 +1517,7 @@ Optional Packages:
--with-krb-srvnam=NAME default service principal name in Kerberos (GSSAPI) --with-krb-srvnam=NAME default service principal name in Kerberos (GSSAPI)
[postgres] [postgres]
--with-pam build with PAM support --with-pam build with PAM support
--with-bsd-auth build with BSD Authentication support
--with-ldap build with LDAP support --with-ldap build with LDAP support
--with-bonjour build with Bonjour support --with-bonjour build with Bonjour support
--with-openssl build with OpenSSL support --with-openssl build with OpenSSL support
...@@ -5570,6 +5572,41 @@ fi ...@@ -5570,6 +5572,41 @@ fi
$as_echo "$with_pam" >&6; } $as_echo "$with_pam" >&6; }
#
# BSD AUTH
#
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build with BSD Authentication support" >&5
$as_echo_n "checking whether to build with BSD Authentication support... " >&6; }
# Check whether --with-bsd-auth was given.
if test "${with_bsd_auth+set}" = set; then :
withval=$with_bsd_auth;
case $withval in
yes)
$as_echo "#define USE_BSD_AUTH 1" >>confdefs.h
;;
no)
:
;;
*)
as_fn_error $? "no argument expected for --with-bsd-auth option" "$LINENO" 5
;;
esac
else
with_bsd_auth=no
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_bsd_auth" >&5
$as_echo "$with_bsd_auth" >&6; }
# #
# LDAP # LDAP
# #
...@@ -10522,6 +10559,17 @@ fi ...@@ -10522,6 +10559,17 @@ fi
done done
fi
if test "$with_bsd_auth" = yes ; then
ac_fn_c_check_header_mongrel "$LINENO" "bsd_auth.h" "ac_cv_header_bsd_auth_h" "$ac_includes_default"
if test "x$ac_cv_header_bsd_auth_h" = xyes; then :
else
as_fn_error $? "header file <bsd_auth.h> is required for BSD Authentication support" "$LINENO" 5
fi
fi fi
if test "$with_systemd" = yes ; then if test "$with_systemd" = yes ; then
......
...@@ -673,6 +673,16 @@ PGAC_ARG_BOOL(with, pam, no, ...@@ -673,6 +673,16 @@ PGAC_ARG_BOOL(with, pam, no,
AC_MSG_RESULT([$with_pam]) AC_MSG_RESULT([$with_pam])
#
# BSD AUTH
#
AC_MSG_CHECKING([whether to build with BSD Authentication support])
PGAC_ARG_BOOL(with, bsd-auth, no,
[build with BSD Authentication support],
[AC_DEFINE([USE_BSD_AUTH], 1, [Define to 1 to build with BSD Authentication support. (--with-bsd-auth)])])
AC_MSG_RESULT([$with_bsd_auth])
# #
# LDAP # LDAP
# #
...@@ -1269,6 +1279,10 @@ if test "$with_pam" = yes ; then ...@@ -1269,6 +1279,10 @@ if test "$with_pam" = yes ; then
[AC_MSG_ERROR([header file <security/pam_appl.h> or <pam/pam_appl.h> is required for PAM.])])]) [AC_MSG_ERROR([header file <security/pam_appl.h> or <pam/pam_appl.h> is required for PAM.])])])
fi fi
if test "$with_bsd_auth" = yes ; then
AC_CHECK_HEADER(bsd_auth.h, [], [AC_MSG_ERROR([header file <bsd_auth.h> is required for BSD Authentication support])])
fi
if test "$with_systemd" = yes ; then if test "$with_systemd" = yes ; then
AC_CHECK_HEADER(systemd/sd-daemon.h, [], [AC_MSG_ERROR([header file <systemd/sd-daemon.h> is required for systemd support])]) AC_CHECK_HEADER(systemd/sd-daemon.h, [], [AC_MSG_ERROR([header file <systemd/sd-daemon.h> is required for systemd support])])
fi fi
......
...@@ -522,6 +522,16 @@ hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable> ...@@ -522,6 +522,16 @@ hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable>
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><literal>bsd</></term>
<listitem>
<para>
Authenticate using the BSD Authentication service provided by the
operating system. See <xref linkend="auth-bsd"> for details.
</para>
</listitem>
</varlistentry>
</variablelist> </variablelist>
</para> </para>
...@@ -1662,6 +1672,41 @@ host ... ldap ldapurl="ldap://ldap.example.net/dc=example,dc=net?uid?sub" ...@@ -1662,6 +1672,41 @@ host ... ldap ldapurl="ldap://ldap.example.net/dc=example,dc=net?uid?sub"
</para> </para>
</note> </note>
</sect2> </sect2>
<sect2 id="auth-bsd">
<title>BSD Authentication</title>
<indexterm zone="auth-bsd">
<primary>BSD Authentication</primary>
</indexterm>
<para>
This authentication method operates similarly to
<literal>password</literal> except that it uses BSD Authentication
to verify the password. BSD Authentication is used only
to validate user name/password pairs. Therefore the user's role must
already exist in the database before BSD Authentication can be used
for authentication. The BSD Authentication framework is currently
only available on OpenBSD.
</para>
<para>
BSD Authentication in <productname>PostgreSQL</> uses
the <literal>auth-postgresql</literal> login type and authenticates with
the <literal>postgresql</literal> login class if that's defined
in <filename>login.conf</filename>. By default that login class does not
exist, and <productname>PostgreSQL</> will use the default login class.
</para>
<note>
<para>
To use BSD Authentication, the PostgreSQL user account (that is, the
operating system user running the server) must first be added to
the <literal>auth</literal> group. The <literal>auth</literal> group
exists by default on OpenBSD systems.
</para>
</note>
</sect2>
</sect1> </sect1>
<sect1 id="client-authentication-problems"> <sect1 id="client-authentication-problems">
......
...@@ -792,6 +792,17 @@ su - postgres ...@@ -792,6 +792,17 @@ su - postgres
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><option>--with-bsd-auth</option></term>
<listitem>
<para>
Build with BSD Authentication support.
(The BSD Authentication framework is
currently only available on OpenBSD.)
</para>
</listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term><option>--with-ldap</option></term> <term><option>--with-ldap</option></term>
<listitem> <listitem>
......
...@@ -88,6 +88,17 @@ static Port *pam_port_cludge; /* Workaround for passing "Port *port" into ...@@ -88,6 +88,17 @@ static Port *pam_port_cludge; /* Workaround for passing "Port *port" into
#endif /* USE_PAM */ #endif /* USE_PAM */
/*----------------------------------------------------------------
* BSD authentication
*----------------------------------------------------------------
*/
#ifdef USE_BSD_AUTH
#include <bsd_auth.h>
static int CheckBSDAuth(Port *port, char *user);
#endif /* USE_BSD_AUTH */
/*---------------------------------------------------------------- /*----------------------------------------------------------------
* LDAP authentication * LDAP authentication
*---------------------------------------------------------------- *----------------------------------------------------------------
...@@ -258,6 +269,9 @@ auth_failed(Port *port, int status, char *logdetail) ...@@ -258,6 +269,9 @@ auth_failed(Port *port, int status, char *logdetail)
case uaPAM: case uaPAM:
errstr = gettext_noop("PAM authentication failed for user \"%s\""); errstr = gettext_noop("PAM authentication failed for user \"%s\"");
break; break;
case uaBSD:
errstr = gettext_noop("BSD authentication failed for user \"%s\"");
break;
case uaLDAP: case uaLDAP:
errstr = gettext_noop("LDAP authentication failed for user \"%s\""); errstr = gettext_noop("LDAP authentication failed for user \"%s\"");
break; break;
...@@ -529,6 +543,14 @@ ClientAuthentication(Port *port) ...@@ -529,6 +543,14 @@ ClientAuthentication(Port *port)
#endif /* USE_PAM */ #endif /* USE_PAM */
break; break;
case uaBSD:
#ifdef USE_BSD_AUTH
status = CheckBSDAuth(port, port->user_name);
#else
Assert(false);
#endif /* USE_BSD_AUTH */
break;
case uaLDAP: case uaLDAP:
#ifdef USE_LDAP #ifdef USE_LDAP
status = CheckLDAPAuth(port); status = CheckLDAPAuth(port);
...@@ -1856,6 +1878,38 @@ CheckPAMAuth(Port *port, char *user, char *password) ...@@ -1856,6 +1878,38 @@ CheckPAMAuth(Port *port, char *user, char *password)
#endif /* USE_PAM */ #endif /* USE_PAM */
/*----------------------------------------------------------------
* BSD authentication system
*----------------------------------------------------------------
*/
#ifdef USE_BSD_AUTH
static int
CheckBSDAuth(Port *port, char *user)
{
char *passwd;
int retval;
/* Send regular password request to client, and get the response */
sendAuthRequest(port, AUTH_REQ_PASSWORD);
passwd = recv_password_packet(port);
if (passwd == NULL)
return STATUS_EOF;
/*
* Ask the BSD auth system to verify password. Note that auth_userokay
* will overwrite the password string with zeroes, but it's just a
* temporary string so we don't care.
*/
retval = auth_userokay(user, NULL, "auth-postgresql", passwd);
if (!retval)
return STATUS_ERROR;
return STATUS_OK;
}
#endif /* USE_BSD_AUTH */
/*---------------------------------------------------------------- /*----------------------------------------------------------------
* LDAP authentication system * LDAP authentication system
......
...@@ -1189,6 +1189,12 @@ parse_hba_line(List *line, int line_num, char *raw_line) ...@@ -1189,6 +1189,12 @@ parse_hba_line(List *line, int line_num, char *raw_line)
parsedline->auth_method = uaPAM; parsedline->auth_method = uaPAM;
#else #else
unsupauth = "pam"; unsupauth = "pam";
#endif
else if (strcmp(token->string, "bsd") == 0)
#ifdef USE_BSD_AUTH
parsedline->auth_method = uaBSD;
#else
unsupauth = "bsd";
#endif #endif
else if (strcmp(token->string, "ldap") == 0) else if (strcmp(token->string, "ldap") == 0)
#ifdef USE_LDAP #ifdef USE_LDAP
......
...@@ -90,6 +90,9 @@ static const char *const auth_methods_host[] = { ...@@ -90,6 +90,9 @@ static const char *const auth_methods_host[] = {
#ifdef USE_PAM #ifdef USE_PAM
"pam", "pam ", "pam", "pam ",
#endif #endif
#ifdef USE_BSD_AUTH
"bsd",
#endif
#ifdef USE_LDAP #ifdef USE_LDAP
"ldap", "ldap",
#endif #endif
...@@ -103,6 +106,9 @@ static const char *const auth_methods_local[] = { ...@@ -103,6 +106,9 @@ static const char *const auth_methods_local[] = {
#ifdef USE_PAM #ifdef USE_PAM
"pam", "pam ", "pam", "pam ",
#endif #endif
#ifdef USE_BSD_AUTH
"bsd",
#endif
#ifdef USE_LDAP #ifdef USE_LDAP
"ldap", "ldap",
#endif #endif
......
...@@ -27,6 +27,7 @@ typedef enum UserAuth ...@@ -27,6 +27,7 @@ typedef enum UserAuth
uaGSS, uaGSS,
uaSSPI, uaSSPI,
uaPAM, uaPAM,
uaBSD,
uaLDAP, uaLDAP,
uaCert, uaCert,
uaRADIUS, uaRADIUS,
......
...@@ -793,6 +793,9 @@ ...@@ -793,6 +793,9 @@
/* Define to 1 to build with Bonjour support. (--with-bonjour) */ /* Define to 1 to build with Bonjour support. (--with-bonjour) */
#undef USE_BONJOUR #undef USE_BONJOUR
/* Define to 1 to build with BSD Authentication support. (--with-bsd-auth) */
#undef USE_BSD_AUTH
/* Define to 1 if you want float4 values to be passed by value. /* Define to 1 if you want float4 values to be passed by value.
(--enable-float4-byval) */ (--enable-float4-byval) */
#undef USE_FLOAT4_BYVAL #undef USE_FLOAT4_BYVAL
......
...@@ -613,6 +613,9 @@ ...@@ -613,6 +613,9 @@
/* Define to 1 to build with Bonjour support. (--with-bonjour) */ /* Define to 1 to build with Bonjour support. (--with-bonjour) */
/* #undef USE_BONJOUR */ /* #undef USE_BONJOUR */
/* Define to 1 to build with BSD Authentication support. (--with-bsd-auth) */
/* #undef USE_BSD_AUTH */
/* Define to 1 if you want 64-bit integer timestamp and interval support. /* Define to 1 if you want 64-bit integer timestamp and interval support.
(--enable-integer-datetimes) */ (--enable-integer-datetimes) */
/* #undef USE_INTEGER_DATETIMES */ /* #undef USE_INTEGER_DATETIMES */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment