diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index 5b0444190ca400eab1fb594323b4a4c704e2ae74..df0ad527ae42e20b78869451ebcb65761d6221ba 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -1,5 +1,5 @@
 <!--
-$PostgreSQL: pgsql/doc/src/sgml/libpq.sgml,v 1.199 2005/11/04 23:14:00 petere Exp $
+$PostgreSQL: pgsql/doc/src/sgml/libpq.sgml,v 1.200 2005/12/23 01:16:37 tgl Exp $
 -->
 
  <chapter id="libpq">
@@ -3565,6 +3565,40 @@ void PQuntrace(PGconn *conn);
 
 </sect1>
 
+<sect1 id="libpq-misc">
+<title>Miscellaneous Functions</title>
+
+<para>
+As always, there are some functions that just don't fit anywhere.
+</para>
+
+<variablelist>
+<varlistentry>
+<term><function>pg_make_encrypted_password</function><indexterm><primary>pg_make_encrypted_password</></></term>
+<listitem>
+<para>
+Prepares the encrypted form of a <productname>PostgreSQL</> password.
+<synopsis>
+char *pg_make_encrypted_password(const char *passwd, const char *user);
+</synopsis>
+<function>pg_make_encrypted_password</> is intended to be used by client
+applications that wish to send commands like
+<literal>ALTER USER joe PASSWORD 'pwd'</>.
+It is good practice not to send the original cleartext password in such a
+command, because it might be exposed in command logs, activity displays,
+and so on.  Instead, use this function to convert the password to encrypted
+form before it is sent.  The arguments are the cleartext password, and the SQL
+name of the user it is for.  The return value is a malloc'd string, or NULL if
+out-of-memory.  The caller may assume the string doesn't contain any weird
+characters that would require escaping.  Use <function>PQfreemem</> to free
+the result when done with it.
+</para>
+</listitem>
+</varlistentry>
+</variablelist>
+
+</sect1>
+
 <sect1 id="libpq-notice-processing">
 <title>Notice Processing</title>
 
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c
index 35da9cdf8297f1921d0c8b9a2183e7cf85d7f2db..6e5ddf53696d7204512ba194975e7ad151d76631 100644
--- a/src/bin/psql/command.c
+++ b/src/bin/psql/command.c
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 2000-2005, PostgreSQL Global Development Group
  *
- * $PostgreSQL: pgsql/src/bin/psql/command.c,v 1.156 2005/12/18 02:17:16 petere Exp $
+ * $PostgreSQL: pgsql/src/bin/psql/command.c,v 1.157 2005/12/23 01:16:38 tgl Exp $
  */
 #include "postgres_fe.h"
 #include "command.h"
@@ -12,7 +12,6 @@
 #undef mkdir
 #endif
 
-#include <errno.h>
 #include <ctype.h>
 #ifdef HAVE_PWD_H
 #include <pwd.h>
@@ -35,7 +34,6 @@
 
 #include "libpq-fe.h"
 #include "pqexpbuffer.h"
-#include "libpq/crypt.h"
 #include "dumputils.h"
 
 #include "common.h"
@@ -638,14 +636,16 @@ exec_command(const char *cmd,
 		{
 			char	   *opt0 = psql_scan_slash_option(scan_state, OT_SQLID, NULL, true);
 			char	   *user;
-			char		encrypted_password[MD5_PASSWD_LEN + 1];
+			char	   *encrypted_password;
 
 			if (opt0)
 				user = opt0;
 			else
 				user = PQuser(pset.db);
 
-			if (!pg_md5_encrypt(pw1, user, strlen(user), encrypted_password))
+			encrypted_password = pg_make_encrypted_password(pw1, user);
+
+			if (!encrypted_password)
 			{
 				fprintf(stderr, _("Password encryption failed.\n"));
 				success = false;
@@ -656,7 +656,7 @@ exec_command(const char *cmd,
 				PGresult   *res;
 
 				initPQExpBuffer(&buf);
-				printfPQExpBuffer(&buf, "ALTER ROLE %s PASSWORD '%s';",
+				printfPQExpBuffer(&buf, "ALTER USER %s PASSWORD '%s';",
 								  fmtId(user), encrypted_password);
 				res = PSQLexec(buf.data, false);
 				termPQExpBuffer(&buf);
@@ -664,6 +664,7 @@ exec_command(const char *cmd,
 					success = false;
 				else
 					PQclear(res);
+				PQfreemem(encrypted_password);
 			}
 		}
 
diff --git a/src/bin/scripts/createuser.c b/src/bin/scripts/createuser.c
index adf9c41b3a2ee2854f9172844d076a9d1dba6854..9bd7d8d873c3f18fe9f6f990176669629a330e56 100644
--- a/src/bin/scripts/createuser.c
+++ b/src/bin/scripts/createuser.c
@@ -5,7 +5,7 @@
  * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/bin/scripts/createuser.c,v 1.24 2005/12/18 02:17:16 petere Exp $
+ * $PostgreSQL: pgsql/src/bin/scripts/createuser.c,v 1.25 2005/12/23 01:16:38 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -13,7 +13,6 @@
 #include "postgres_fe.h"
 #include "common.h"
 #include "dumputils.h"
-#include "libpq/crypt.h"
 
 
 static void help(const char *progname);
@@ -250,14 +249,17 @@ main(int argc, char *argv[])
 
 		if (encrypted != TRI_NO)
 		{
-			char		encrypted_password[MD5_PASSWD_LEN + 1];
+			char	   *encrypted_password;
 
-			if (!pg_md5_encrypt(newpassword, newuser, strlen(newuser), encrypted_password))
+			encrypted_password = pg_make_encrypted_password(newpassword,
+															newuser);
+			if (!encrypted_password)
 			{
 				fprintf(stderr, _("Password encryption failed.\n"));
 				exit(1);
 			}
 			appendStringLiteral(&sql, encrypted_password, false);
+			PQfreemem(encrypted_password);
 		}
 		else
 			appendStringLiteral(&sql, newpassword, false);
diff --git a/src/interfaces/libpq/exports.txt b/src/interfaces/libpq/exports.txt
index bcb18f829cea05549fcc8fbd1c4166a0a4670f3f..3b95bccb467e6fe8b2f9d35a7ca1761f8221dd63 100644
--- a/src/interfaces/libpq/exports.txt
+++ b/src/interfaces/libpq/exports.txt
@@ -1,4 +1,4 @@
-# $PostgreSQL: pgsql/src/interfaces/libpq/exports.txt,v 1.5 2005/10/21 15:21:21 tgl Exp $
+# $PostgreSQL: pgsql/src/interfaces/libpq/exports.txt,v 1.6 2005/12/23 01:16:38 tgl Exp $
 # Functions to be exported by libpq DLLs
 PQconnectdb               1
 PQsetdbLogin              2
@@ -125,3 +125,4 @@ PQcancel                  122
 lo_create                 123
 PQinitSSL                 124
 PQregisterThreadLock      125
+pg_make_encrypted_password 126
diff --git a/src/interfaces/libpq/fe-auth.c b/src/interfaces/libpq/fe-auth.c
index 95609114f9977d90f3f0e524a07c1ddd1ca6cad9..039964a9fe5a2bbf2fab56d91867cdec643e741b 100644
--- a/src/interfaces/libpq/fe-auth.c
+++ b/src/interfaces/libpq/fe-auth.c
@@ -10,7 +10,7 @@
  * exceed INITIAL_EXPBUFFER_SIZE (currently 256 bytes).
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/interfaces/libpq/fe-auth.c,v 1.108 2005/11/22 18:17:32 momjian Exp $
+ *	  $PostgreSQL: pgsql/src/interfaces/libpq/fe-auth.c,v 1.109 2005/12/23 01:16:38 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -531,3 +531,40 @@ pg_fe_getauthname(char *PQerrormsg)
 
 	return authn;
 }
+
+
+/*
+ * pg_make_encrypted_password -- exported routine to encrypt a password
+ *
+ * This is intended to be used by client applications that wish to send
+ * commands like ALTER USER joe PASSWORD 'pwd'.  The password need not
+ * be sent in cleartext if it is encrypted on the client side.  This is
+ * good because it ensures the cleartext password won't end up in logs,
+ * pg_stat displays, etc.  We export the function so that clients won't
+ * be dependent on low-level details like whether the enceyption is MD5
+ * or something else.
+ *
+ * Arguments are the cleartext password, and the SQL name of the user it
+ * is for.
+ *
+ * Return value is a malloc'd string, or NULL if out-of-memory.  The client
+ * may assume the string doesn't contain any weird characters that would
+ * require escaping.
+ */
+char *
+pg_make_encrypted_password(const char *passwd, const char *user)
+{
+	char	   *crypt_pwd;
+
+	crypt_pwd = malloc(MD5_PASSWD_LEN + 1);
+	if (!crypt_pwd)
+		return NULL;
+
+	if (!pg_md5_encrypt(passwd, user, strlen(user), crypt_pwd))
+	{
+		free(crypt_pwd);
+		return NULL;
+	}
+
+	return crypt_pwd;
+}
diff --git a/src/interfaces/libpq/libpq-fe.h b/src/interfaces/libpq/libpq-fe.h
index f0f0cede54eed9bbec7381ac6c67dabc6fb32f33..fc42c2b28a783617a789857ccae5b96af1c0eedc 100644
--- a/src/interfaces/libpq/libpq-fe.h
+++ b/src/interfaces/libpq/libpq-fe.h
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/interfaces/libpq/libpq-fe.h,v 1.122 2005/11/23 04:23:28 momjian Exp $
+ * $PostgreSQL: pgsql/src/interfaces/libpq/libpq-fe.h,v 1.123 2005/12/23 01:16:38 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -495,6 +495,10 @@ extern int	PQdsplen(const char *s, int encoding);
 /* Get encoding id from environment variable PGCLIENTENCODING */
 extern int	PQenv2encoding(void);
 
+/* === in fe-auth.c === */
+
+extern char *pg_make_encrypted_password(const char *passwd, const char *user);
+
 #ifdef __cplusplus
 }
 #endif