diff --git a/configure b/configure index 24655dc09614ee72f882abad90a0d071a1e5f51e..e09eb5fb5310a7ea4d26e451b2775da294c1a95c 100755 --- a/configure +++ b/configure @@ -827,6 +827,7 @@ with_python with_gssapi with_krb_srvnam with_pam +with_bsd_auth with_ldap with_bonjour with_openssl @@ -1516,6 +1517,7 @@ Optional Packages: --with-krb-srvnam=NAME default service principal name in Kerberos (GSSAPI) [postgres] --with-pam build with PAM support + --with-bsd-auth build with BSD Authentication support --with-ldap build with LDAP support --with-bonjour build with Bonjour support --with-openssl build with OpenSSL support @@ -5570,6 +5572,41 @@ fi $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 # @@ -10522,6 +10559,17 @@ fi 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 if test "$with_systemd" = yes ; then diff --git a/configure.in b/configure.in index c564a7695fa917e664f5c5676c8dc95468fad4e5..bc925d0e1bcea8f5f67df12eb3d96db8f33e8f75 100644 --- a/configure.in +++ b/configure.in @@ -673,6 +673,16 @@ PGAC_ARG_BOOL(with, pam, no, 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 # @@ -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.])])]) 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 AC_CHECK_HEADER(systemd/sd-daemon.h, [], [AC_MSG_ERROR([header file <systemd/sd-daemon.h> is required for systemd support])]) fi diff --git a/doc/src/sgml/client-auth.sgml b/doc/src/sgml/client-auth.sgml index 7b204fb48e71dc60e8f125664d7b551b73fc66f1..28973e2c2b4d5206e9fe8433015126444856fc57 100644 --- a/doc/src/sgml/client-auth.sgml +++ b/doc/src/sgml/client-auth.sgml @@ -522,6 +522,16 @@ hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable> </para> </listitem> </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> </para> @@ -1662,6 +1672,41 @@ host ... ldap ldapurl="ldap://ldap.example.net/dc=example,dc=net?uid?sub" </para> </note> </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 id="client-authentication-problems"> diff --git a/doc/src/sgml/installation.sgml b/doc/src/sgml/installation.sgml index 1564b8ea04ee09a4233f33b487964b1d7f60c038..a9968756e652f2232b6bcca79665fe86f098cd8d 100644 --- a/doc/src/sgml/installation.sgml +++ b/doc/src/sgml/installation.sgml @@ -792,6 +792,17 @@ su - postgres </listitem> </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> <term><option>--with-ldap</option></term> <listitem> diff --git a/src/backend/libpq/auth.c b/src/backend/libpq/auth.c index 630762cc6b979fba00e6f1afd528417f6a32171b..dbba712352f83bb11ac003b62e1602af130c2bb7 100644 --- a/src/backend/libpq/auth.c +++ b/src/backend/libpq/auth.c @@ -88,6 +88,17 @@ static Port *pam_port_cludge; /* Workaround for passing "Port *port" into #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 *---------------------------------------------------------------- @@ -258,6 +269,9 @@ auth_failed(Port *port, int status, char *logdetail) case uaPAM: errstr = gettext_noop("PAM authentication failed for user \"%s\""); break; + case uaBSD: + errstr = gettext_noop("BSD authentication failed for user \"%s\""); + break; case uaLDAP: errstr = gettext_noop("LDAP authentication failed for user \"%s\""); break; @@ -529,6 +543,14 @@ ClientAuthentication(Port *port) #endif /* USE_PAM */ break; + case uaBSD: +#ifdef USE_BSD_AUTH + status = CheckBSDAuth(port, port->user_name); +#else + Assert(false); +#endif /* USE_BSD_AUTH */ + break; + case uaLDAP: #ifdef USE_LDAP status = CheckLDAPAuth(port); @@ -1856,6 +1878,38 @@ CheckPAMAuth(Port *port, char *user, char *password) #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 diff --git a/src/backend/libpq/hba.c b/src/backend/libpq/hba.c index 5a397464d759e20ed5a73ae83a3322b2b4ea4b2c..a4c415da77a1b17484b62e9cbde5b3dda2d87317 100644 --- a/src/backend/libpq/hba.c +++ b/src/backend/libpq/hba.c @@ -1189,6 +1189,12 @@ parse_hba_line(List *line, int line_num, char *raw_line) parsedline->auth_method = uaPAM; #else unsupauth = "pam"; +#endif + else if (strcmp(token->string, "bsd") == 0) +#ifdef USE_BSD_AUTH + parsedline->auth_method = uaBSD; +#else + unsupauth = "bsd"; #endif else if (strcmp(token->string, "ldap") == 0) #ifdef USE_LDAP diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c index 18a3826b003bbc5be5432400dc3cdadda4d03db2..299ddfe86ac41e1a5a6cfe5234475e9b846a518c 100644 --- a/src/bin/initdb/initdb.c +++ b/src/bin/initdb/initdb.c @@ -90,6 +90,9 @@ static const char *const auth_methods_host[] = { #ifdef USE_PAM "pam", "pam ", #endif +#ifdef USE_BSD_AUTH + "bsd", +#endif #ifdef USE_LDAP "ldap", #endif @@ -103,6 +106,9 @@ static const char *const auth_methods_local[] = { #ifdef USE_PAM "pam", "pam ", #endif +#ifdef USE_BSD_AUTH + "bsd", +#endif #ifdef USE_LDAP "ldap", #endif diff --git a/src/include/libpq/hba.h b/src/include/libpq/hba.h index b306baf1a56ffc4d9e2c18f9d2ad5a9218afef01..58f90fec80d3563936f776549b7ada33f0887fea 100644 --- a/src/include/libpq/hba.h +++ b/src/include/libpq/hba.h @@ -27,6 +27,7 @@ typedef enum UserAuth uaGSS, uaSSPI, uaPAM, + uaBSD, uaLDAP, uaCert, uaRADIUS, diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in index c72635ca963ff13e13ae3a0d4c8b0cf16cc7c3d6..b621ff2af57172779a506aedcb53fd9f8c838872 100644 --- a/src/include/pg_config.h.in +++ b/src/include/pg_config.h.in @@ -793,6 +793,9 @@ /* Define to 1 to build with Bonjour support. (--with-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. (--enable-float4-byval) */ #undef USE_FLOAT4_BYVAL diff --git a/src/include/pg_config.h.win32 b/src/include/pg_config.h.win32 index eba36df92e0b5403df5de119ab8072ac0a7c6639..c135e5146b4081e2c897fcc0d3db0b7e200b7e00 100644 --- a/src/include/pg_config.h.win32 +++ b/src/include/pg_config.h.win32 @@ -613,6 +613,9 @@ /* Define to 1 to build with Bonjour support. (--with-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. (--enable-integer-datetimes) */ /* #undef USE_INTEGER_DATETIMES */