I've attached the latest version of this patch. I've fixed up an issue with the configuration scripts that I missed.

On 08/01/16 12:40, Marisa Emerson wrote:
There's a port for PAM, but we would prefer to use BSD Auth as its quite
a lot cleaner and is standard on OpenBSD.

I've attached an updated patch that includes documentation. It has been
tested against OpenBSD 5.8. I'll add this thread to the commitfest.

On 07/01/16 23:26, Greg Stark wrote:
This sounds like a sensible thing to me. I'm actually surprised, it
sounds like something we would have already seen. Do some people just
use PAM on OpenBSD? Are both supported?

You should add the patch to https://commitfest.postgresql.org to
ensure it doesn't slip through the cracks. It's too late for January
though there's nothing stopping people from commenting on or even
committing patches outside the commitfest.

diff --git a/configure b/configure
index 5772d0e..84c1c3e 100755
--- a/configure
+++ b/configure
@@ -826,6 +826,7 @@ with_python
 with_gssapi
 with_krb_srvnam
 with_pam
+with_bsd_auth
 with_ldap
 with_bonjour
 with_openssl
@@ -1514,6 +1515,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
@@ -5557,6 +5559,41 @@ $as_echo "$with_pam" >&6; }
 
 
 #
+# BSD AUTH
+#
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build with BSD support" >&5
+$as_echo_n "checking whether to build with BSD 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
 #
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build with LDAP support" >&5
@@ -10475,6 +10512,23 @@ done
 
 fi
 
+if test "$with_bsd_auth" = yes ; then
+  for ac_header in bsd_auth.h
+do :
+  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 :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_BSD_AUTH_H 1
+_ACEOF
+
+else
+  as_fn_error $? "header file <bsd_auth.h> is required for BSD Authentication support" "$LINENO" 5
+fi
+
+done
+
+fi
+
 if test "$with_libxml" = yes ; then
   ac_fn_c_check_header_mongrel "$LINENO" "libxml/parser.h" "ac_cv_header_libxml_parser_h" "$ac_includes_default"
 if test "x$ac_cv_header_libxml_parser_h" = xyes; then :
diff --git a/configure.in b/configure.in
index 44f832f..8eb98a8 100644
--- a/configure.in
+++ b/configure.in
@@ -663,6 +663,16 @@ AC_MSG_RESULT([$with_pam])
 
 
 #
+# BSD AUTH
+#
+AC_MSG_CHECKING([whether to build with BSD 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 support. (--with-bsd-auth)])])
+AC_MSG_RESULT([$with_bsd_auth])
+
+
+#
 # LDAP
 #
 AC_MSG_CHECKING([whether to build with LDAP support])
@@ -1249,6 +1259,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_HEADERS(bsd_auth.h, [], [AC_MSG_ERROR([header file <bsd_auth.h> is required for BSD Authentication support])])
+fi
+
 if test "$with_libxml" = yes ; then
   AC_CHECK_HEADER(libxml/parser.h, [], [AC_MSG_ERROR([header file <libxml/parser.h> is required for XML support])])
 fi
diff --git a/doc/src/sgml/client-auth.sgml b/doc/src/sgml/client-auth.sgml
index 3b2935c..ffb5178 100644
--- a/doc/src/sgml/client-auth.sgml
+++ b/doc/src/sgml/client-auth.sgml
@@ -522,6 +522,17 @@ hostnossl  <replaceable>database</replaceable>  <replaceable>user</replaceable>
          </para>
         </listitem>
        </varlistentry>
+
+       <varlistentry>
+         <term><literal>bsd</></term>
+         <listitem>
+          <para>
+           Authenticate using BSD Authentication (BSD Auth) provided
+           by the operating system. See <xref linkend="auth-bsd">
+           for details.
+          </para>
+         </listitem>
+       </varlistentry>
       </variablelist>
 
       </para>
@@ -1647,6 +1658,30 @@ 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</primary>
+   </indexterm>
+
+   <para>
+    This authentication method operates similarly to
+    <literal>password</literal> except that it uses BSD
+    Authentication as the authentication mechanism. BSD Authentication
+    is used only to validate user name/password pairs.
+    Therefore the user must already exist in the database before BSD
+    Authentication can be used for authentication.
+   </para>
+
+   <note>
+    <para>
+    To use BSD Authentication, the postgresql user must first be added
+    to the <literal>auth</literal> group.
+    </para>
+   </note>
+  </sect2>
  </sect1>
 
   <sect1 id="client-authentication-problems">
diff --git a/src/backend/libpq/auth.c b/src/backend/libpq/auth.c
index cdc5bf1..43673fa 100644
--- a/src/backend/libpq/auth.c
+++ b/src/backend/libpq/auth.c
@@ -89,6 +89,16 @@ static Port *pam_port_cludge;	/* Workaround for passing "Port *port" into
 
 
 /*----------------------------------------------------------------
+ * 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 +268,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 +542,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);
@@ -1828,7 +1849,32 @@ CheckPAMAuth(Port *port, char *user, char *password)
 }
 #endif   /* USE_PAM */
 
+/*----------------------------------------------------------------
+ * BSD authentication system
+ *----------------------------------------------------------------
+ */
+#ifdef USE_BSD_AUTH
+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;
+
+	retval = auth_userokay(user, NULL, "pg-auth", 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 94f7cfa..220f8b3 100644
--- a/src/backend/libpq/hba.c
+++ b/src/backend/libpq/hba.c
@@ -1190,6 +1190,12 @@ parse_hba_line(List *line, int line_num, char *raw_line)
 #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
 		parsedline->auth_method = uaLDAP;
diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c
index a27706f..8b26627 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 68a953a..0e2a61b 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 16a272e..e347d1b 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -821,6 +821,9 @@
 /* Define to 1 to build with PAM support. (--with-pam) */
 #undef USE_PAM
 
+/* Define to 1 to build with BSD support. (--with-bsd-auth) */
+#undef USE_BSD_AUTH
+
 /* Use replacement snprintf() functions. */
 #undef USE_REPL_SNPRINTF
 
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to