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

Lines changed: 10 additions & 8 deletions
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

Lines changed: 42 additions & 42 deletions
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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy