Index: contrib/dblink/dblink.c
===================================================================
RCS file: /opt/src/cvs/pgsql/contrib/dblink/dblink.c,v
retrieving revision 1.74
diff -c -r1.74 dblink.c
*** contrib/dblink/dblink.c	3 Jul 2008 03:56:57 -0000	1.74
--- contrib/dblink/dblink.c	22 Sep 2008 00:34:17 -0000
***************
*** 93,98 ****
--- 93,99 ----
  static HeapTuple get_tuple_of_interest(Oid relid, int2vector *pkattnums, int16 pknumatts, char **src_pkattvals);
  static Oid	get_relid_from_relname(text *relname_text);
  static char *generate_relation_name(Oid relid);
+ static void dblink_connstr_check(const char *connstr);
  static void dblink_security_check(PGconn *conn, remoteConn *rconn);
  static void dblink_res_error(const char *conname, PGresult *res, const char *dblink_context_msg, bool fail);
  
***************
*** 165,170 ****
--- 166,172 ----
  			else \
  			{ \
  				connstr = conname_or_str; \
+ 				dblink_connstr_check(connstr); \
  				conn = PQconnectdb(connstr); \
  				if (PQstatus(conn) == CONNECTION_BAD) \
  				{ \
***************
*** 229,234 ****
--- 231,239 ----
  
  	if (connname)
  		rconn = (remoteConn *) palloc(sizeof(remoteConn));
+ 
+ 	/* check password in connection string if not superuser */
+ 	dblink_connstr_check(connstr);
  	conn = PQconnectdb(connstr);
  
  	MemoryContextSwitchTo(oldcontext);
***************
*** 246,252 ****
  				 errdetail("%s", msg)));
  	}
  
! 	/* check password used if not superuser */
  	dblink_security_check(conn, rconn);
  
  	if (connname)
--- 251,257 ----
  				 errdetail("%s", msg)));
  	}
  
! 	/* check password actually used if not superuser */
  	dblink_security_check(conn, rconn);
  
  	if (connname)
***************
*** 2252,2257 ****
--- 2257,2293 ----
  }
  
  static void
+ dblink_connstr_check(const char *connstr)
+ {
+ 	if (!superuser())
+ 	{
+ 		PQconninfoOption   *options;
+ 		PQconninfoOption   *option;
+ 		bool				conn_used_password = false;
+ 
+ 		options = PQconninfoParse(connstr);
+ 		for (option = options; option->keyword != NULL; option++)
+ 		{
+ 			if (strcmp(option->keyword, "password") == 0)
+ 			{
+ 				if (option->val != NULL && option->val[0] != '\0')
+ 				{
+ 					conn_used_password = true;
+ 					break;
+ 				}
+ 			}
+ 		}
+ 		PQconninfoFree(options);
+ 
+ 		if (!conn_used_password)
+ 			ereport(ERROR,
+ 				  (errcode(ERRCODE_S_R_E_PROHIBITED_SQL_STATEMENT_ATTEMPTED),
+ 				   errmsg("password is required"),
+ 				   errdetail("Non-superuser must provide a password in the connection string.")));
+ 	}
+ }
+ 
+ static void
  dblink_res_error(const char *conname, PGresult *res, const char *dblink_context_msg, bool fail)
  {
  	int			level;
Index: doc/src/sgml/libpq.sgml
===================================================================
RCS file: /opt/src/cvs/pgsql/doc/src/sgml/libpq.sgml,v
retrieving revision 1.263
diff -c -r1.263 libpq.sgml
*** doc/src/sgml/libpq.sgml	19 Sep 2008 20:06:13 -0000	1.263
--- doc/src/sgml/libpq.sgml	21 Sep 2008 23:08:27 -0000
***************
*** 625,630 ****
--- 625,658 ----
      </varlistentry>
  
      <varlistentry>
+      <term><function>PQconninfoParse</function><indexterm><primary>PQconninfoParse</></></term>
+      <listitem>
+       <para>
+        Returns parsed connection options from the provided connection string.
+ 
+ <synopsis>
+ PQconninfoOption *PQconninfoParse(const char *conninfo);
+ </synopsis>
+ 
+       <para>
+        Returns a connection options array.  This can be used to determine
+        the <function>PQconnectdb</function> options in the provided
+        connection string.  The return value points to an array of
+        <structname>PQconninfoOption</structname> structures, which ends
+        with an entry having a null <structfield>keyword</> pointer.  The
+        null pointer is returned if memory could not be allocated.
+       </para>
+ 
+       <para>
+        After processing the options array, free it by passing it to
+        <function>PQconninfoFree</function>.  If this is not done, a small amount of memory
+        is leaked for each call to <function>PQconndefaults</function>.
+       </para>
+ 
+    </listitem>
+     </varlistentry>
+ 
+     <varlistentry>
       <term><function>PQfinish</function><indexterm><primary>PQfinish</></></term>
       <listitem>
        <para>
Index: src/interfaces/libpq/exports.txt
===================================================================
RCS file: /opt/src/cvs/pgsql/src/interfaces/libpq/exports.txt,v
retrieving revision 1.21
diff -c -r1.21 exports.txt
*** src/interfaces/libpq/exports.txt	19 Sep 2008 20:06:13 -0000	1.21
--- src/interfaces/libpq/exports.txt	21 Sep 2008 23:32:56 -0000
***************
*** 151,153 ****
--- 151,154 ----
  PQresultInstanceData      149
  PQresultSetInstanceData   150
  PQfireResultCreateEvents  151
+ PQconninfoParse           152
Index: src/interfaces/libpq/fe-connect.c
===================================================================
RCS file: /opt/src/cvs/pgsql/src/interfaces/libpq/fe-connect.c,v
retrieving revision 1.360
diff -c -r1.360 fe-connect.c
*** src/interfaces/libpq/fe-connect.c	17 Sep 2008 04:31:08 -0000	1.360
--- src/interfaces/libpq/fe-connect.c	21 Sep 2008 22:56:40 -0000
***************
*** 3101,3106 ****
--- 3101,3127 ----
  	return 0;
  }
  
+ /*
+  *		PQconninfoParse
+  *
+  * Parse a string like PQconnectdb() would do and return the
+  * working connection options array.
+  *
+  * NOTE: the returned array is dynamically allocated and should
+  * be freed when no longer needed via PQconninfoFree().
+  */
+ PQconninfoOption *
+ PQconninfoParse(const char *conninfo)
+ {
+ 	PQExpBufferData		errorBuf;
+ 	bool				password_from_string;
+ 	PQconninfoOption   *connOptions;
+ 
+ 	initPQExpBuffer(&errorBuf);
+ 	connOptions = conninfo_parse(conninfo, &errorBuf, &password_from_string);
+ 	termPQExpBuffer(&errorBuf);
+ 	return connOptions;
+ }
  
  /*
   * Conninfo parser routine
Index: src/interfaces/libpq/libpq-fe.h
===================================================================
RCS file: /opt/src/cvs/pgsql/src/interfaces/libpq/libpq-fe.h,v
retrieving revision 1.143
diff -c -r1.143 libpq-fe.h
*** src/interfaces/libpq/libpq-fe.h	17 Sep 2008 04:31:08 -0000	1.143
--- src/interfaces/libpq/libpq-fe.h	21 Sep 2008 22:57:37 -0000
***************
*** 243,248 ****
--- 243,251 ----
  /* get info about connection options known to PQconnectdb */
  extern PQconninfoOption *PQconndefaults(void);
  
+ /* parse connection options in same way as PQconnectdb */
+ extern PQconninfoOption *PQconninfoParse(const char *conninfo);
+ 
  /* free the data structure returned by PQconndefaults() */
  extern void PQconninfoFree(PQconninfoOption *connOptions);
  
