Add BSD authentication method.
authorTom Lane <tgl@sss.pgh.pa.us>
Fri, 8 Apr 2016 17:51:54 +0000 (13:51 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Fri, 8 Apr 2016 17:52:06 +0000 (13:52 -0400)
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

configure
configure.in
doc/src/sgml/client-auth.sgml
doc/src/sgml/installation.sgml
src/backend/libpq/auth.c
src/backend/libpq/hba.c
src/bin/initdb/initdb.c
src/include/libpq/hba.h
src/include/pg_config.h.in
src/include/pg_config.h.win32

index 24655dc09614ee72f882abad90a0d071a1e5f51e..e09eb5fb5310a7ea4d26e451b2775da294c1a95c 100755 (executable)
--- 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
 #
 
 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
index c564a7695fa917e664f5c5676c8dc95468fad4e5..bc925d0e1bcea8f5f67df12eb3d96db8f33e8f75 100644 (file)
@@ -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
index 7b204fb48e71dc60e8f125664d7b551b73fc66f1..28973e2c2b4d5206e9fe8433015126444856fc57 100644 (file)
@@ -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">
index 1564b8ea04ee09a4233f33b487964b1d7f60c038..a9968756e652f2232b6bcca79665fe86f098cd8d 100644 (file)
@@ -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>
index 630762cc6b979fba00e6f1afd528417f6a32171b..dbba712352f83bb11ac003b62e1602af130c2bb7 100644 (file)
@@ -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
index 5a397464d759e20ed5a73ae83a3322b2b4ea4b2c..a4c415da77a1b17484b62e9cbde5b3dda2d87317 100644 (file)
@@ -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
index 18a3826b003bbc5be5432400dc3cdadda4d03db2..299ddfe86ac41e1a5a6cfe5234475e9b846a518c 100644 (file)
@@ -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
index b306baf1a56ffc4d9e2c18f9d2ad5a9218afef01..58f90fec80d3563936f776549b7ada33f0887fea 100644 (file)
@@ -27,6 +27,7 @@ typedef enum UserAuth
        uaGSS,
        uaSSPI,
        uaPAM,
+       uaBSD,
        uaLDAP,
        uaCert,
        uaRADIUS,
index c72635ca963ff13e13ae3a0d4c8b0cf16cc7c3d6..b621ff2af57172779a506aedcb53fd9f8c838872 100644 (file)
 /* 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
index eba36df92e0b5403df5de119ab8072ac0a7c6639..c135e5146b4081e2c897fcc0d3db0b7e200b7e00 100644 (file)
 /* 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 */