Skip to content

Commit f35252d

Browse files
committed
Fix pg_passwd's failure to cope with usernames > 8 chars.
1 parent a24b04d commit f35252d

File tree

2 files changed

+52
-50
lines changed

2 files changed

+52
-50
lines changed

doc/src/sgml/ref/pg_passwd.sgml

+10-8
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!--
2-
$Header: /cvsroot/pgsql/doc/src/sgml/ref/Attic/pg_passwd.sgml,v 1.5 2000/12/25 23:15:26 petere Exp $
2+
$Header: /cvsroot/pgsql/doc/src/sgml/ref/Attic/pg_passwd.sgml,v 1.6 2001/02/20 01:16:49 tgl Exp $
33
Postgres documentation
44
-->
55

@@ -31,7 +31,7 @@ Postgres documentation
3131
<para>
3232
<application>pg_passwd</application> is a tool to manipulate a flat
3333
text password file for the purpose of using that file to control
34-
the client authentication of the
34+
client authentication of the
3535
<productname>PostgreSQL</productname> server. More information
3636
about setting up this authentication mechanism can be found in the
3737
<citetitle>Administrator's Guide</citetitle>.
@@ -51,7 +51,7 @@ Postgres documentation
5151
<para>
5252
Supply the name of the password file as argument to the <application>pg_passwd</application>
5353
command. To be of use for client authentication the file needs to
54-
be location in the server's data directory, and the base name of
54+
be located in the server's data directory, and the base name of
5555
the file needs to be specified in the
5656
<filename>pg_hba.conf</filename> access control file.
5757

@@ -65,7 +65,9 @@ Postgres documentation
6565

6666
where the <literal>Password:</literal> and <literal>Re-enter
6767
password:</literal> prompts require the same password input which
68-
is not displayed on the terminal.
68+
is not displayed on the terminal. Note that the password is limited
69+
to eight useful characters by restrictions of the standard crypt(3)
70+
library routine.
6971
</para>
7072

7173
<para>
@@ -78,12 +80,12 @@ Postgres documentation
7880
<filename>pg_hba.conf</filename>:
7981

8082
<programlisting>
81-
host unv 133.65.96.250 255.255.255.255 password passwords
83+
host mydb 133.65.96.250 255.255.255.255 password passwords
8284
</programlisting>
8385

84-
which would allow access from host 133.65.96.250 using the
85-
passwords listed in the <filename>passwords</filename> file (and
86-
only to the users listed in the file).
86+
which would allow access to database mydb from host 133.65.96.250 using
87+
the passwords listed in the <filename>passwords</filename> file (and
88+
only to the users listed in that file).
8789
</para>
8890

8991
<note>

src/bin/pg_passwd/pg_passwd.c

+42-42
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,23 @@ extern char *crypt(const char *, const char *);
1919

2020
#endif
2121

22-
#define PG_PASSWD_LEN 13 /* not including null */
22+
/*
23+
* We assume that the output of crypt(3) is always 13 characters,
24+
* and that at most 8 characters can usefully be sent to it.
25+
*
26+
* Postgres usernames are assumed to be less than NAMEDATALEN chars long.
27+
*/
28+
#define CLEAR_PASSWD_LEN 8 /* not including null */
29+
#define CRYPTED_PASSWD_LEN 13 /* not including null */
2330

2431
const char * progname;
2532

2633
static void usage(void);
2734
static void read_pwd_file(char *filename);
2835
static void write_pwd_file(char *filename, char *bkname);
29-
static void encrypt_pwd(char key[9], char salt[3], char passwd[PG_PASSWD_LEN+1]);
36+
static void encrypt_pwd(char key[CLEAR_PASSWD_LEN+1],
37+
char salt[3],
38+
char passwd[CRYPTED_PASSWD_LEN+1]);
3039
static void prompt_for_username(char *username);
3140
static void prompt_for_password(char *prompt, char *password);
3241

@@ -94,7 +103,9 @@ read_pwd_file(char *filename)
94103
}
95104

96105
/* read all the entries */
97-
for (npwds = 0; npwds < MAXPWDS && fgets(line, 512, fp) != NULL; ++npwds)
106+
for (npwds = 0;
107+
npwds < MAXPWDS && fgets(line, sizeof(line), fp) != NULL;
108+
++npwds)
98109
{
99110
int l;
100111
char *p,
@@ -123,13 +134,13 @@ read_pwd_file(char *filename)
123134
}
124135
pwds[npwds].uname = strdup(p);
125136

126-
/* check duplicate */
137+
/* check for duplicate user name */
127138
for (i = 0; i < npwds; ++i)
128139
{
129140
if (strcmp(pwds[i].uname, pwds[npwds].uname) == 0)
130141
{
131-
fprintf(stderr, "Duplicated entry: %s\n",
132-
pwds[npwds].uname);
142+
fprintf(stderr, "Duplicate username %s in entry %d\n",
143+
pwds[npwds].uname, npwds+1);
133144
exit(1);
134145
}
135146
}
@@ -143,7 +154,7 @@ read_pwd_file(char *filename)
143154
if (q != NULL)
144155
*(q++) = '\0';
145156

146-
if (strlen(p) != PG_PASSWD_LEN && strcmp(p, "+")!=0)
157+
if (strlen(p) != CRYPTED_PASSWD_LEN && strcmp(p, "+") != 0)
147158
{
148159
fprintf(stderr, "%s:%d: warning: invalid password length\n",
149160
filename, npwds + 1);
@@ -209,11 +220,13 @@ write_pwd_file(char *filename, char *bkname)
209220
}
210221

211222
static void
212-
encrypt_pwd(char key[9], char salt[3], char passwd[PG_PASSWD_LEN + 1])
223+
encrypt_pwd(char key[CLEAR_PASSWD_LEN+1],
224+
char salt[3],
225+
char passwd[CRYPTED_PASSWD_LEN+1])
213226
{
214227
int n;
215228

216-
/* get encrypted password */
229+
/* select a salt, if not already given */
217230
if (salt[0] == '\0')
218231
{
219232
srand(time(NULL));
@@ -229,32 +242,16 @@ encrypt_pwd(char key[9], char salt[3], char passwd[PG_PASSWD_LEN + 1])
229242
salt[1] = n;
230243
salt[2] = '\0';
231244
}
245+
246+
/* get encrypted password */
232247
strcpy(passwd, crypt(key, salt));
233248

249+
#ifdef PG_PASSWD_DEBUG
234250
/* show it */
235-
236-
/*
237-
* fprintf(stderr, "key = %s, salt = %s, password = %s\n", key, salt,
238-
* passwd);
239-
*/
240-
}
241-
242-
#ifdef NOT_USED
243-
static int
244-
check_pwd(char key[9], char passwd[PG_PASSWD_LEN + 1])
245-
{
246-
char shouldbe[PG_PASSWD_LEN + 1];
247-
char salt[3];
248-
249-
salt[0] = passwd[0];
250-
salt[1] = passwd[1];
251-
salt[2] = '\0';
252-
encrypt_pwd(key, salt, shouldbe);
253-
254-
return strncmp(shouldbe, passwd, PG_PASSWD_LEN) == 0 ? 1 : 0;
255-
}
256-
251+
fprintf(stderr, "key = %s, salt = %s, password = %s\n",
252+
key, salt, passwd);
257253
#endif
254+
}
258255

259256
static void
260257
prompt_for_username(char *username)
@@ -263,7 +260,7 @@ prompt_for_username(char *username)
263260

264261
printf("Username: ");
265262
fflush(stdout);
266-
if (fgets(username, 9, stdin) == NULL)
263+
if (fgets(username, NAMEDATALEN, stdin) == NULL)
267264
username[0] = '\0';
268265

269266
length = strlen(username);
@@ -295,16 +292,19 @@ prompt_for_password(char *prompt, char *password)
295292

296293
#endif
297294

298-
printf(prompt);
299-
fflush(stdout);
300295
#ifdef HAVE_TERMIOS_H
301296
tcgetattr(0, &t);
302297
t_orig = t;
303298
t.c_lflag &= ~ECHO;
304299
tcsetattr(0, TCSADRAIN, &t);
305300
#endif
306-
if (fgets(password, 9, stdin) == NULL)
301+
302+
printf(prompt);
303+
fflush(stdout);
304+
305+
if (fgets(password, CLEAR_PASSWD_LEN+1, stdin) == NULL)
307306
password[0] = '\0';
307+
308308
#ifdef HAVE_TERMIOS_H
309309
tcsetattr(0, TCSADRAIN, &t_orig);
310310
#endif
@@ -332,13 +332,13 @@ prompt_for_password(char *prompt, char *password)
332332
int
333333
main(int argc, char *argv[])
334334
{
335-
static char bkname[MAXPGPATH];
336335
char *filename;
337-
char username[9];
336+
char bkname[MAXPGPATH];
337+
char username[NAMEDATALEN];
338338
char salt[3];
339-
char key[9],
340-
key2[9];
341-
char e_passwd[PG_PASSWD_LEN + 1];
339+
char key[CLEAR_PASSWD_LEN + 1],
340+
key2[CLEAR_PASSWD_LEN + 1];
341+
char e_passwd[CRYPTED_PASSWD_LEN + 1];
342342
int i;
343343

344344
progname = argv[0];
@@ -376,7 +376,7 @@ main(int argc, char *argv[])
376376
prompt_for_username(username);
377377
prompt_for_password("New password: ", key);
378378
prompt_for_password("Re-enter new password: ", key2);
379-
if (strncmp(key, key2, 8) != 0)
379+
if (strcmp(key, key2) != 0)
380380
{
381381
fprintf(stderr, "Password mismatch\n");
382382
exit(1);
@@ -397,7 +397,7 @@ main(int argc, char *argv[])
397397
{ /* did not exist */
398398
if (npwds == MAXPWDS)
399399
{
400-
fprintf(stderr, "Cannot handle so may entries\n");
400+
fprintf(stderr, "Cannot handle so many entries\n");
401401
exit(1);
402402
}
403403
pwds[npwds].uname = strdup(username);

0 commit comments

Comments
 (0)