From e7029b212755594bbfb4325fffd2dbd7b00eef08 Mon Sep 17 00:00:00 2001
From: Bruce Momjian <bruce@momjian.us>
Date: Sun, 1 Aug 2004 05:59:13 +0000
Subject: [PATCH] >I got a new idea on this.  I think we should add an initdb
 option that >takes a string to specify the local authentication method: > >  
     initdb --auth 'ident' > >or whatever the user wants.  I think this is
 more flexible and more >compact.  It would default to 'trust', and the
 packagers could >set it to >whatever they want.  If their OS supports local
 ident, they can use >that. > >Also keep in mind you might want some ident map
 file: > >       initdb --auth 'ident mymap' > >so you would need to allow
 multiple words in the string.

Magnus Hagander
---
 src/backend/libpq/pg_hba.conf.sample | 14 ++----
 src/bin/initdb/initdb.c              | 71 ++++++++++++++++++++++++++--
 2 files changed, 73 insertions(+), 12 deletions(-)

diff --git a/src/backend/libpq/pg_hba.conf.sample b/src/backend/libpq/pg_hba.conf.sample
index bd9120676a..e857b12bdc 100644
--- a/src/backend/libpq/pg_hba.conf.sample
+++ b/src/backend/libpq/pg_hba.conf.sample
@@ -48,20 +48,16 @@
 # Put your actual configuration here
 # ----------------------------------
 #
-# CAUTION: The default configuration allows any local user to connect
-# using any PostgreSQL user name, including the superuser, over either
-# Unix-domain sockets or TCP/IP.  If you are on a multiple-user
-# machine, the default configuration is probably too liberal for you.
-# Change it to use something other than "trust" authentication.
-#
 # If you want to allow non-local connections, you need to add more
 # "host" records.  Also, remember TCP/IP connections are only enabled
 # if you enable "tcpip_socket" in postgresql.conf.
 
+@authcomment@
+
 # TYPE  DATABASE    USER        IP-ADDRESS        IP-MASK           METHOD
 
-local   all         all                                             trust
+local   all         all                                             @authmethod@
 # IPv4-style local connections:
-host    all         all         127.0.0.1         255.255.255.255   trust
+host    all         all         127.0.0.1         255.255.255.255   @authmethod@
 # IPv6-style local connections:
-host    all         all         ::1/128                             trust
+host    all         all         ::1/128                             @authmethod@
diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c
index ad71289ba2..cd830ecda7 100644
--- a/src/bin/initdb/initdb.c
+++ b/src/bin/initdb/initdb.c
@@ -39,7 +39,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  * Portions taken from FreeBSD.
  *
- * $PostgreSQL: pgsql/src/bin/initdb/initdb.c,v 1.44 2004/07/19 02:47:12 tgl Exp $
+ * $PostgreSQL: pgsql/src/bin/initdb/initdb.c,v 1.45 2004/08/01 05:59:13 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -88,6 +88,7 @@ char	   *lc_messages = "";
 char	   *username = "";
 bool		pwprompt = false;
 char       *pwfilename = NULL;
+char       *authmethod = "";
 bool		debug = false;
 bool		noclean = false;
 bool		show_setting = false;
@@ -118,6 +119,16 @@ bool		output_failed = false;
 int			n_connections = 10;
 int			n_buffers = 50;
 
+/*
+ * Warning messages for authentication methods
+ */
+char *authtrust_warning =											\
+	"# CAUTION: Configuring the system for local \"trust\" authentication allows\n"
+	"# any local user to connect as any PostgreSQL user, including the database\n"
+	"# superuser. If you do not trust all your local users, use another\n"
+	"# authenication method.\n";
+char *authwarning = NULL;
+
 /*
  * Centralized knowledge of switches to pass to backend
  *
@@ -1114,7 +1125,16 @@ setup_config(void)
 							  "host    all         all         ::1",
 							  "#host    all         all         ::1");
 #endif
-
+	
+	/* Replace default authentication methods */
+	conflines = replace_token(conflines,
+							 "@authmethod@",
+							  authmethod);
+	
+	conflines = replace_token(conflines,
+							  "@authcomment@",
+							  strcmp(authmethod,"trust") ? "" : authtrust_warning);
+		
 	snprintf(path, sizeof(path), "%s/pg_hba.conf", pg_data);
 
 	writefile(path, conflines);
@@ -1971,6 +1991,7 @@ usage(const char *progname)
 			 "                            in the respective category (default taken from\n"
 			 "                            environment)\n"));
 	printf(_("  --no-locale               equivalent to --locale=C\n"));
+	printf(_("  -A, --auth=method         default authentication method for local connections\n"));
 	printf(_("  -U, --username=NAME       database superuser name\n"));
 	printf(_("  -W, --pwprompt            prompt for a password for the new superuser\n"));
 	printf(_("  --pwfile=filename         read password for the new superuser from file\n"));
@@ -2004,6 +2025,7 @@ main(int argc, char *argv[])
 		{"lc-time", required_argument, NULL, 6},
 		{"lc-messages", required_argument, NULL, 7},
 		{"no-locale", no_argument, NULL, 8},
+		{"auth", required_argument, NULL, 'A'}, 
 		{"pwprompt", no_argument, NULL, 'W'},
 		{"pwfile", required_argument, NULL, 9},
 		{"username", required_argument, NULL, 'U'},
@@ -2052,10 +2074,13 @@ main(int argc, char *argv[])
 
 	/* process command-line options */
 
-	while ((c = getopt_long(argc, argv, "dD:E:L:nU:W", long_options, &option_index)) != -1)
+	while ((c = getopt_long(argc, argv, "dD:E:L:nU:WA:", long_options, &option_index)) != -1)
 	{
 		switch (c)
 		{
+			case 'A':
+				authmethod = xstrdup(optarg);
+				break;
 			case 'D':
 				pg_data = xstrdup(optarg);
 				break;
@@ -2136,6 +2161,43 @@ main(int argc, char *argv[])
 		fprintf(stderr, _("%s: you cannot specify both password prompt and password file\n"), progname);
 		exit(1);
 	}
+	
+	if (authmethod == NULL || !strlen(authmethod))
+	{
+		authwarning = _("\nWARNING: enabling \"trust\" authentication for local connections.\n"
+						"You can change this by editing pg_hba.conf or using the -A flag the\n"
+						"next time you run initdb.\n");
+		authmethod="trust";
+	}
+
+	if (strcmp(authmethod,"md5") &&
+		strcmp(authmethod,"ident") && 
+		strncmp(authmethod,"ident ",6) && /* ident with space = param */
+		strcmp(authmethod,"trust") &&
+#ifdef USE_PAM
+		strcmp(authmethod,"pam") &&
+		strncmp(authmethod,"pam ",4) && /* pam with space = param */
+#endif
+		strcmp(authmethod,"crypt") &&
+		strcmp(authmethod,"password")
+		)
+		/*
+		 *	Kerberos methods not listed because they are not supported
+		 * 	over local connections and are rejected in hba.c
+		 */
+	{
+		fprintf(stderr, _("%s: unknown authentication method \"%s\".\n"), progname, authmethod);
+		exit(1);
+	}
+
+	if ((!strcmp(authmethod,"md5") ||
+		 !strcmp(authmethod,"crypt") ||
+		 !strcmp(authmethod,"password")) &&
+		 !(pwprompt || pwfilename))
+	{
+		fprintf(stderr, _("%s: you need to specify a password for the superuser to enable %s authentication.\n"), progname, authmethod);
+		exit(1);
+	}
 
 	if (strlen(pg_data) == 0)
 	{
@@ -2449,6 +2511,9 @@ main(int argc, char *argv[])
 
 	make_template0();
 
+	if (authwarning != NULL)
+		fprintf(stderr, authwarning);
+
 	printf(_("\nSuccess. You can now start the database server using:\n\n"
 		   "    %s%s%s/postmaster -D %s%s%s\n"
 		   "or\n"