(unnamed)

text/plain

Filename: (unnamed)
Type: text/plain
Part: 0
Message: Re: [BUGS] Bug #756: suggestion: file with password instead of
Index: doc/src/sgml/libpq.sgml
===================================================================
RCS file: /cvsroot/pgsql-server/doc/src/sgml/libpq.sgml,v
retrieving revision 1.94
diff -c -c -r1.94 libpq.sgml
*** doc/src/sgml/libpq.sgml	2 Sep 2002 20:21:32 -0000	1.94
--- doc/src/sgml/libpq.sgml	5 Sep 2002 21:46:31 -0000
***************
*** 2052,2074 ****
  </listitem>
  <listitem>
  <para>
- <indexterm>
-  <primary><envar>PGPASSWORDFILE</envar></primary>
- </indexterm>
- <envar>PGPASSWORDFILE</envar>
- sets the password file used if the backend demands password authentication.
- This file should have the format
- <screen>
- <replaceable>hostname</replaceable>:<replaceable>port</replaceable>:<replaceable>database</replaceable>:<replaceable>username</replaceable>:<replaceable>password</replaceable>
- </screen>
- Any of these may be a literal name, or a <literal>*</literal> that matches
- anything.  The first match will be the one used, so put more specific entries first.
- Entries with <literal>:</literal> or <literal>\</literal> should be escaped
- with <literal>\</literal>.
- </para>
- </listitem>
- <listitem>
- <para>
  <envar>PGREALM</envar> sets the Kerberos realm to  use  with  
  <productname>PostgreSQL</productname>, if  it is different from the local realm.
  If <envar>PGREALM</envar> is set, <productname>PostgreSQL</productname> 
--- 2052,2057 ----
***************
*** 2139,2144 ****
--- 2122,2148 ----
  for information on correct values for these environment variables.
  </para>
  
+ </sect1>
+ 
+ 
+ <sect1 id="libpq-files">
+ <title>Files</title>
+ 
+ <indexterm zone="libpq-files">
+  <primary>files</primary>
+ </indexterm>
+ <para>
+ <filename>$HOME/.pgpass</filename> is a file that can contain passwords
+ to be used if the connection requires a password. This file should have the
+ format:
+ <screen>
+ <replaceable>hostname</replaceable>:<replaceable>port</replaceable>:<replaceable>database</replaceable>:<replaceable>username</replaceable>:<replaceable>password</replaceable>
+ </screen>
+ Any of these may be a literal name, or <literal>*</literal>, which matches
+ anything.  The first match will be used so put more specific entries first.
+ Entries with <literal>:</literal> or <literal>\</literal> should be escaped
+ with <literal>\</literal>.
+ </para>
  </sect1>
  
  <sect1 id="libpq-threading">
Index: doc/src/sgml/ref/clusterdb.sgml
===================================================================
RCS file: /cvsroot/pgsql-server/doc/src/sgml/ref/clusterdb.sgml,v
retrieving revision 1.2
diff -c -c -r1.2 clusterdb.sgml
*** doc/src/sgml/ref/clusterdb.sgml	3 Sep 2002 01:11:37 -0000	1.2
--- doc/src/sgml/ref/clusterdb.sgml	5 Sep 2002 21:46:32 -0000
***************
*** 54,63 ****
    </para>
  
    <para>
!   <application>clusterdb</application> will need to connect several times to the
!   <productname>PostgreSQL</productname> server.  If you are using password
!   authentication, it will ask for the password each time. It will probably be
!   very convenient to have a PGPASSWORDFILE in that case.
    </para>
  
   </refsect1>
--- 54,63 ----
    </para>
  
    <para>
!   <application>clusterdb</application> might need to connect several
!   times to the <productname>PostgreSQL</productname> server, asking for
!   a password each time. It is convenient to have a
!   <filename>$HOME/.pgpass</> file in such cases.
    </para>
  
   </refsect1>
Index: doc/src/sgml/ref/pg_dumpall.sgml
===================================================================
RCS file: /cvsroot/pgsql-server/doc/src/sgml/ref/pg_dumpall.sgml,v
retrieving revision 1.32
diff -c -c -r1.32 pg_dumpall.sgml
*** doc/src/sgml/ref/pg_dumpall.sgml	27 Aug 2002 18:57:26 -0000	1.32
--- doc/src/sgml/ref/pg_dumpall.sgml	5 Sep 2002 21:46:34 -0000
***************
*** 61,66 ****
--- 61,74 ----
     The SQL script will be written to the standard output.  Shell
     operators should be used to redirect it into a file.
    </para>
+ 
+   <para>
+   <application>pg_dumpall</application> might need to connect several
+   times to the <productname>PostgreSQL</productname> server, asking for
+   a password each time. It is convenient to have a
+   <filename>$HOME/.pgpass</> file in such cases.
+   </para>
+ 
   </refsect1>
  
   <refsect1>
Index: doc/src/sgml/ref/vacuumdb.sgml
===================================================================
RCS file: /cvsroot/pgsql-server/doc/src/sgml/ref/vacuumdb.sgml,v
retrieving revision 1.24
diff -c -c -r1.24 vacuumdb.sgml
*** doc/src/sgml/ref/vacuumdb.sgml	27 Aug 2002 03:55:17 -0000	1.24
--- doc/src/sgml/ref/vacuumdb.sgml	5 Sep 2002 21:46:34 -0000
***************
*** 62,70 ****
  
  
    <para>
!   <application>vacuumdb</application> will need to connect several times to the
!   <productname>PostgreSQL</productname> server, asking for the password each
!   time. It will probably be very convenient to have a PGPASSWORDFILE in that case.
    </para>
  
   </refsect1>
--- 62,71 ----
  
  
    <para>
!   <application>vacuumdb</application> might need to connect several
!   times to the <productname>PostgreSQL</productname> server, asking for
!   a password each time. It is convenient to have a
!   <filename>$HOME/.pgpass</> file in such cases.
    </para>
  
   </refsect1>
Index: src/bin/psql/input.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/bin/psql/input.c,v
retrieving revision 1.19
diff -c -c -r1.19 input.c
*** src/bin/psql/input.c	10 Apr 2002 22:46:58 -0000	1.19
--- src/bin/psql/input.c	5 Sep 2002 21:46:38 -0000
***************
*** 30,35 ****
--- 30,37 ----
  static void finishInput(int, void *);
  #endif
  
+ #define PSQLHISTORY	"/.psql_history"
+ 
  
  /*
   * gets_interactive()
***************
*** 142,152 ****
  		home = getenv("HOME");
  		if (home)
  		{
! 			char	   *psql_history = (char *) malloc(strlen(home) + 20);
  
  			if (psql_history)
  			{
! 				sprintf(psql_history, "%s/.psql_history", home);
  				read_history(psql_history);
  				free(psql_history);
  			}
--- 144,155 ----
  		home = getenv("HOME");
  		if (home)
  		{
! 			char	   *psql_history = (char *) malloc(strlen(home) +
! 												strlen(PSQLHISTORY) + 1);
  
  			if (psql_history)
  			{
! 				sprintf(psql_history, "%s" PSQLHISTORY, home);
  				read_history(psql_history);
  				free(psql_history);
  			}
***************
*** 201,214 ****
  		home = getenv("HOME");
  		if (home)
  		{
! 			psql_history = (char *) malloc(strlen(home) + 20);
  			if (psql_history)
  			{
  				const char *var = GetVariable(pset.vars, "HISTSIZE");
  
  				if (var)
  					stifle_history(atoi(var));
! 				sprintf(psql_history, "%s/.psql_history", home);
  				write_history(psql_history);
  				free(psql_history);
  			}
--- 204,218 ----
  		home = getenv("HOME");
  		if (home)
  		{
! 			psql_history = (char *) malloc(strlen(home) +
! 									strlen(PSQLHISTORY) + 1);
  			if (psql_history)
  			{
  				const char *var = GetVariable(pset.vars, "HISTSIZE");
  
  				if (var)
  					stifle_history(atoi(var));
! 				sprintf(psql_history, "%s" PSQLHISTORY, home);
  				write_history(psql_history);
  				free(psql_history);
  			}
Index: src/bin/psql/startup.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/bin/psql/startup.c,v
retrieving revision 1.64
diff -c -c -r1.64 startup.c
*** src/bin/psql/startup.c	4 Sep 2002 20:31:36 -0000	1.64
--- src/bin/psql/startup.c	5 Sep 2002 21:46:41 -0000
***************
*** 599,622 ****
  #define R_OK 0
  #endif
  
  	/* Look for one in the home dir */
  	home = getenv("HOME");
  
  	if (home)
  	{
! 		psqlrc = malloc(strlen(home) + 20);
  		if (!psqlrc)
  		{
  			fprintf(stderr, gettext("%s: out of memory\n"), pset.progname);
  			exit(EXIT_FAILURE);
  		}
  
! 		sprintf(psqlrc, "%s/.psqlrc-" PG_VERSION, home);
  		if (access(psqlrc, R_OK) == 0)
  			process_file(psqlrc);
  		else
  		{
! 			sprintf(psqlrc, "%s/.psqlrc", home);
  			if (access(psqlrc, R_OK) == 0)
  				process_file(psqlrc);
  		}
--- 599,625 ----
  #define R_OK 0
  #endif
  
+ #define PSQLRC "/.psqlrc"
+ 
  	/* Look for one in the home dir */
  	home = getenv("HOME");
  
  	if (home)
  	{
! 		psqlrc = malloc(strlen(home) + strlen(PSQLRC) + 1 +
! 				 strlen(PG_VERSION) + 1);
  		if (!psqlrc)
  		{
  			fprintf(stderr, gettext("%s: out of memory\n"), pset.progname);
  			exit(EXIT_FAILURE);
  		}
  
! 		sprintf(psqlrc, "%s" PSQLRC "-" PG_VERSION, home);
  		if (access(psqlrc, R_OK) == 0)
  			process_file(psqlrc);
  		else
  		{
! 			sprintf(psqlrc, "%s" PSQLRC, home);
  			if (access(psqlrc, R_OK) == 0)
  				process_file(psqlrc);
  		}
Index: src/interfaces/libpq/fe-connect.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/interfaces/libpq/fe-connect.c,v
retrieving revision 1.201
diff -c -c -r1.201 fe-connect.c
*** src/interfaces/libpq/fe-connect.c	4 Sep 2002 20:31:46 -0000	1.201
--- src/interfaces/libpq/fe-connect.c	5 Sep 2002 21:46:55 -0000
***************
*** 66,71 ****
--- 66,72 ----
  #define NOTIFYLIST_INITIAL_SIZE 10
  #define NOTIFYLIST_GROWBY 10
  
+ #define PGPASSFILE "/.pgpass"
  
  /* ----------
   * Definition of the conninfo parameters and their fallback resources.
***************
*** 186,192 ****
  				 PQExpBuffer errorMessage);
  char	   *pwdfMatchesString(char *buf, char *token);
  char *PasswordFromFile(char *hostname, char *port, char *dbname,
! 				 char *username, char *pwdfile);
  
  /*
   *		Connecting to a Database
--- 187,193 ----
  				 PQExpBuffer errorMessage);
  char	   *pwdfMatchesString(char *buf, char *token);
  char *PasswordFromFile(char *hostname, char *port, char *dbname,
! 					   char *username);
  
  /*
   *		Connecting to a Database
***************
*** 395,404 ****
   *
   *	  PGPASSWORD   The user's password.
   *
-  *	  PGPASSWORDFILE
-  *				   A file that contains host:port:database:user:password
-  *				   for authentication
-  *
   *	  PGDATABASE   name of database to which to connect if <pgdatabase>
   *				   argument is NULL or a null string
   *
--- 396,401 ----
***************
*** 506,513 ****
  	else if ((tmp = getenv("PGPASSWORD")) != NULL)
  		conn->pgpass = strdup(tmp);
  	else if ((tmp = PasswordFromFile(conn->pghost, conn->pgport,
! 									 conn->dbName, conn->pguser,
! 									 getenv("PGPASSWORDFILE"))) != NULL)
  		conn->pgpass = tmp;
  	else
  		conn->pgpass = strdup(DefaultPassword);
--- 503,509 ----
  	else if ((tmp = getenv("PGPASSWORD")) != NULL)
  		conn->pgpass = strdup(tmp);
  	else if ((tmp = PasswordFromFile(conn->pghost, conn->pgport,
! 									 conn->dbName, conn->pguser)))
  		conn->pgpass = tmp;
  	else
  		conn->pgpass = strdup(DefaultPassword);
***************
*** 2905,2926 ****
  
  /* get a password from the password file. */
  char *
! PasswordFromFile(char *hostname, char *port, char *dbname,
! 				 char *username, char *pwdfile)
  {
  	FILE	   *fp;
  
  #define LINELEN NAMEDATALEN*5
  	char		buf[LINELEN];
- 	struct stat stat_buf;
- 
- 	if (pwdfile == NULL || strcmp(pwdfile, "") == 0)
- 		return NULL;
  
! 	if (dbname == NULL || strcmp(dbname, "") == 0)
  		return NULL;
  
! 	if (username == NULL || strcmp(username, "") == 0)
  		return NULL;
  
  	if (hostname == NULL)
--- 2901,2920 ----
  
  /* get a password from the password file. */
  char *
! PasswordFromFile(char *hostname, char *port, char *dbname, char *username)
  {
  	FILE	   *fp;
+ 	char	   *pgpassfile;
+ 	char	   *home;
+ 	struct stat stat_buf;
  
  #define LINELEN NAMEDATALEN*5
  	char		buf[LINELEN];
  
! 	if (dbname == NULL || strlen(dbname) == 0)
  		return NULL;
  
! 	if (username == NULL || strlen(username) == 0)
  		return NULL;
  
  	if (hostname == NULL)
***************
*** 2929,2948 ****
  	if (port == NULL)
  		port = DEF_PGPORT_STR;
  
  	/* If password file cannot be opened, ignore it. */
! 	if (stat(pwdfile, &stat_buf) == -1)
  		return NULL;
  
  	/* If password file is insecure, alert the user and ignore it. */
  	if (stat_buf.st_mode & (S_IRWXG | S_IRWXO))
  	{
  		fprintf(stderr,
  				libpq_gettext("WARNING: Password file %s has world or group read access; permission should be u=rw (0600)"),
! 				pwdfile);
  		return NULL;
  	}
  
! 	fp = fopen(pwdfile, "r");
  	if (fp == NULL)
  		return NULL;
  
--- 2923,2963 ----
  	if (port == NULL)
  		port = DEF_PGPORT_STR;
  
+ 	/* Look for it in the home dir */
+ 	home = getenv("HOME");
+ 	if (home)
+ 	{
+ 		pgpassfile = malloc(strlen(home) + strlen(PGPASSFILE) + 1);
+ 		if (!pgpassfile)
+ 		{
+ 			fprintf(stderr, gettext("%s: out of memory\n"), pset.progname);
+ 			exit(EXIT_FAILURE);
+ 		}
+ 	}
+ 	else
+ 		return NULL;
+ 
+ 	sprintf(pgpassfile, "%s" PGPASSFILE, home);
+ 
  	/* If password file cannot be opened, ignore it. */
! 	if (stat(pgpassfile, &stat_buf) == -1)
! 	{
! 		free(pgpassfile);
  		return NULL;
+ 	}
  
  	/* If password file is insecure, alert the user and ignore it. */
  	if (stat_buf.st_mode & (S_IRWXG | S_IRWXO))
  	{
  		fprintf(stderr,
  				libpq_gettext("WARNING: Password file %s has world or group read access; permission should be u=rw (0600)"),
! 				pgpassfile);
! 		free(pgpassfile);
  		return NULL;
  	}
  
! 	fp = fopen(pgpassfile, "r");
! 	free(pgpassfile);
  	if (fp == NULL)
  		return NULL;
  
***************
*** 2965,2970 ****
--- 2980,2986 ----
  		fclose(fp);
  		return ret;
  	}
+ 
  	fclose(fp);
  	return NULL;