-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hello,

I have found that pg_md5 in md5auth mode can only create a pool_passwd
entry for the unix user running it.  You cannot just edit the username
in pool_passwd afterwards since the hash is created as
md5(PasswordUsername) in PostgreSQL.  Thus the possible ways to add
valid accounts to pool_passwd are :

- - get the hash from pg_shadow (only works if the passwords are encrypted
in the database)
- - create the hash from PasswordUsername with pg_md5 without -m then edit
pool_passwd
- - have a unix account for each user in PostgreSQL (!)

Thus the attached patch (against HEAD rev 1.11) add a --username (or -u)
to pg_md5 to let the administrator create pool_passwd for any role more
easily.  It falls back to the current username when the -u argument is
empty or the option is note given and has no effect when -m is not
specified.  The patch also adds the option to the English documentation,
since I don't know Japanese, I could not update the Japanese version :)


Also, the patch use MAX_INPUT_SIZE for the username buffer, it is
currently 32 bytes, which is quite small for both username and password.
 I think it could be changed to 64 at least, 128 would be best. What do
you think?

Regards,
- -- 
Nicolas Thauvin
DBA
http://www.dalibo.com
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iQIcBAEBAgAGBQJN8TZLAAoJEDa2VZzWZKpNYkcQAJQ/biMWeAKFEcyPRPV59wQK
Tc+0CKi9f626BzA2f13PYSt84xwQHabrBwjpquRmfMleFfsgGHqV2JTxgY3Xsf3c
PmGLp9gLDZaLYp7zZEED35oQ8meSAMpTT1o5PFvCDrp5oZCSymUy6RoGRfjbQ4w/
JEjhdsO+3dJ/D9UX3C5et2R9KLk6J7xSF03RfKlR72yZNDOmSvaJcn+3IHr/rBGE
SNcNkv76cp2PwCc66q5XH2Qo2HEttXNKbjCmSCgTKwgdJS9IroZsQ+JvJqY6TdBl
JwuTtzNGMii1eryJRu6bMacvvBHxGz12W82+uekmW69ivYT2QMDUDpayGVbcWA0q
E28DvbU1JAPKBwlSt+rPERw1dSL8xhUTxMdE22mfL9wG6CcbJ6lEzUaRqzLviWeJ
I2Oy+Ycicj+jCLK4j8JX7TWFPh2qYJFmCOY2LhYVRQFz08oBXeNXRS7OUVJS6fSX
P9OQRsF0Kq9ChQeGbtrXL8uZZT9GhFzU+0FGV3jDF/R4pQuUvKCz+qSBEh52X0sR
eGww6DRsoBz3kzRCcbegJI4GBChzvLozNQ65/0YxA06XJ1dmKfP3zyIY/2VNEUpD
R61HK+qpzoTOjj4IbZBNqt/R3rOxC4F+luV0Zr2cMf0b6aABHxVyzlTyzBOe4tAp
doCVgRYIBvNKOpkvJI3O
=jEdW
-----END PGP SIGNATURE-----
Index: pg_md5.c
===================================================================
RCS file: /cvsroot/pgpool/pgpool-II/pg_md5.c,v
retrieving revision 1.11
diff -u -p -r1.11 pg_md5.c
--- pg_md5.c	13 Jan 2011 06:10:05 -0000	1.11
+++ pg_md5.c	7 Jun 2011 21:23:52 -0000
@@ -45,7 +45,7 @@
 
 static void	print_usage(const char prog[], int exit_code);
 static void	set_tio_attr(int enable);
-static void update_pool_passwd(char *conf_file, char *password);
+static void update_pool_passwd(char *conf_file, char *username, char *password);
 
 int
 main(int argc, char *argv[])
@@ -53,6 +53,7 @@ main(int argc, char *argv[])
 #define PRINT_USAGE(exit_code)	print_usage(argv[0], exit_code)
 
 	char conf_file[POOLMAXPATHLEN+1];
+	char username[MAX_INPUT_SIZE+1];
 	int opt;
 	int optindex;
 	bool md5auth = false;
@@ -62,14 +63,19 @@ main(int argc, char *argv[])
 		{"help", no_argument, NULL, 'h'},
 		{"prompt", no_argument, NULL, 'p'},
 		{"md5auth", no_argument, NULL, 'm'},
-		{"md5auth", no_argument, NULL, 'm'},
+		{"username", required_argument, NULL, 'u'},
 		{"config-file", required_argument, NULL, 'f'},
 		{NULL, 0, NULL, 0}
 	};
 
 	snprintf(conf_file, sizeof(conf_file), "%s/%s", DEFAULT_CONFIGDIR, POOL_CONF_FILE_NAME);
 
-    while ((opt = getopt_long(argc, argv, "hpmf:", long_options, &optindex)) != -1)
+	/* initialize username buffer with zeros so that we can use strlen on it later
+	   to check if a username was given on the command line
+	 */
+	memset(username, 0, MAX_INPUT_SIZE+1);
+
+    while ((opt = getopt_long(argc, argv, "hpmf:u:", long_options, &optindex)) != -1)
 	{
 		switch (opt)
 		{
@@ -89,6 +95,20 @@ main(int argc, char *argv[])
 				strncpy(conf_file, optarg, sizeof(conf_file));
 				break;
 
+			case 'u':
+				if (!optarg)
+				{
+					PRINT_USAGE(EXIT_SUCCESS);
+				}
+				/* check the input limit early */
+				if (strlen(optarg) > MAX_INPUT_SIZE)
+				{
+					fprintf(stderr, "Error: input exceeds maximum username length!\n\n");
+					exit(EXIT_FAILURE);
+				}
+				strncpy(username, optarg, sizeof(username));
+				break;
+
 			default:
 				PRINT_USAGE(EXIT_SUCCESS);
 				break;
@@ -125,7 +145,7 @@ main(int argc, char *argv[])
 
 		if (md5auth)
 		{
-			update_pool_passwd(conf_file, buf);
+			update_pool_passwd(conf_file, username, buf);
 		}
 		else
 		{
@@ -155,7 +175,7 @@ main(int argc, char *argv[])
 
 		if (md5auth)
 		{
-			update_pool_passwd(conf_file, argv[optind]);
+			update_pool_passwd(conf_file, username, argv[optind]);
 		}
 		else
 		{
@@ -167,7 +187,7 @@ main(int argc, char *argv[])
 	return EXIT_SUCCESS;
 }
 
-static void update_pool_passwd(char *conf_file, char *password)
+static void update_pool_passwd(char *conf_file, char *username, char *password)
 {
 	struct passwd *pw;
 	char	 md5[MD5_PASSWD_LEN+1];
@@ -192,14 +212,24 @@ static void update_pool_passwd(char *con
 			 dirp, pool_config->pool_passwd);
 	pool_init_pool_passwd(pool_passwd);
 
-	pw = getpwuid(getuid());
-	if (!pw)
+	if (strlen(username))
 	{
-		fprintf(stderr, "getpwuid() failed\n\n");
-		exit(EXIT_FAILURE);
+		/* generate the hash for the given username */
+		pg_md5_encrypt(password, username, strlen(username), md5);
+		pool_create_passwdent(username, md5);
+	}
+	else
+	{
+		/* get the user information from the current uid */
+		pw = getpwuid(getuid());
+		if (!pw)
+		{
+			fprintf(stderr, "getpwuid() failed\n\n");
+			exit(EXIT_FAILURE);
+		}
+		pg_md5_encrypt(password, pw->pw_name, strlen(pw->pw_name), md5);
+		pool_create_passwdent(pw->pw_name, md5);
 	}
-	pg_md5_encrypt(password, pw->pw_name, strlen(pw->pw_name), md5);
-	pool_create_passwdent(pw->pw_name, md5);
 	pool_finish_pool_passwd();
 }
 
@@ -212,9 +242,11 @@ print_usage(const char prog[], int exit_
   %s [OPTIONS]\n\
   %s <PASSWORD>\n\
 \n\
-  --prompt, -p    Prompt password using standard input.\n\
-  --md5auth, -m   Produce md5 authentication password.\n\
-  --help, -h      This help menu.\n\
+  --prompt, -p         Prompt password using standard input.\n\
+  --md5auth, -m        Produce md5 authentication password.\n\
+  --username, -u USER  When producing a md5 authentication password,\n\
+                       create the pool_passwd entry for USER.\n\
+  --help, -h           This help menu.\n\
 \n\
 Warning: At most %d characters are allowed for input.\n\
 Warning: Plain password argument is deprecated for security concerns\n\
Index: doc/pgpool-en.html
===================================================================
RCS file: /cvsroot/pgpool/pgpool-II/doc/pgpool-en.html,v
retrieving revision 1.91
diff -u -p -r1.91 pgpool-en.html
--- doc/pgpool-en.html	1 May 2011 09:41:48 -0000	1.91
+++ doc/pgpool-en.html	7 Jun 2011 21:23:54 -0000
@@ -2741,7 +2741,7 @@ recovery.
 	   md5 authentication:
 	   <ol>
 		<li>Login as the database's operating system user and type 
-		   "pg_md5 --md5auth <your_passwd>"
+		   "pg_md5 --md5auth --username=<your_username> <your_passwd>"
 			 user name and md5 encrypted password are registered into
 			 pool_passwd.
 			 If pool_passwd does not exist yet, pg_md5 command will

Attachment: pg_md5_username.patch.sig
Description: Binary data

_______________________________________________
Pgpool-hackers mailing list
[email protected]
http://pgfoundry.org/mailman/listinfo/pgpool-hackers

Reply via email to