pg_passwd is a tool to manipulate a flat
text password file for the purpose of using that file to control
- the client authentication of the
+ client authentication of the
PostgreSQL server. More information
about setting up this authentication mechanism can be found in the
Administrator's Guide.
Supply the name of the password file as argument to the
pg_passwd
command. To be of use for client authentication the file needs to
- be location in the server's data directory, and the base name of
+ be located in the server's data directory, and the base name of
the file needs to be specified in the
pg_hba.conf access control file.
where the Password: and Re-enter
password: prompts require the same password input which
- is not displayed on the terminal.
+ is not displayed on the terminal. Note that the password is limited
+ to eight useful characters by restrictions of the standard crypt(3)
+ library routine.
pg_hba.conf:
-host unv 133.65.96.250 255.255.255.255 password passwords
+host mydb 133.65.96.250 255.255.255.255 password passwords
- which would allow access from host 133.65.96.250 using the
- passwords listed in the passwords file (and
- only to the users listed in the file).
+ which would allow access to database mydb from host 133.65.96.250 using
+ the passwords listed in the passwords file (and
+ only to the users listed in that file).
#endif
-#define PG_PASSWD_LEN 13 /* not including null */
+/*
+ * We assume that the output of crypt(3) is always 13 characters,
+ * and that at most 8 characters can usefully be sent to it.
+ *
+ * Postgres usernames are assumed to be less than NAMEDATALEN chars long.
+ */
+#define CLEAR_PASSWD_LEN 8 /* not including null */
+#define CRYPTED_PASSWD_LEN 13 /* not including null */
const char * progname;
static void usage(void);
static void read_pwd_file(char *filename);
static void write_pwd_file(char *filename, char *bkname);
-static void encrypt_pwd(char key[9], char salt[3], char passwd[PG_PASSWD_LEN+1]);
+static void encrypt_pwd(char key[CLEAR_PASSWD_LEN+1],
+ char salt[3],
+ char passwd[CRYPTED_PASSWD_LEN+1]);
static void prompt_for_username(char *username);
static void prompt_for_password(char *prompt, char *password);
}
/* read all the entries */
- for (npwds = 0; npwds < MAXPWDS && fgets(line, 512, fp) != NULL; ++npwds)
+ for (npwds = 0;
+ npwds < MAXPWDS && fgets(line, sizeof(line), fp) != NULL;
+ ++npwds)
{
int l;
char *p,
}
pwds[npwds].uname = strdup(p);
- /* check duplicate */
+ /* check for duplicate user name */
for (i = 0; i < npwds; ++i)
{
if (strcmp(pwds[i].uname, pwds[npwds].uname) == 0)
{
- fprintf(stderr, "Duplicated entry: %s\n",
- pwds[npwds].uname);
+ fprintf(stderr, "Duplicate username %s in entry %d\n",
+ pwds[npwds].uname, npwds+1);
exit(1);
}
}
if (q != NULL)
*(q++) = '\0';
- if (strlen(p) != PG_PASSWD_LEN && strcmp(p, "+")!=0)
+ if (strlen(p) != CRYPTED_PASSWD_LEN && strcmp(p, "+") != 0)
{
fprintf(stderr, "%s:%d: warning: invalid password length\n",
filename, npwds + 1);
}
static void
-encrypt_pwd(char key[9], char salt[3], char passwd[PG_PASSWD_LEN + 1])
+encrypt_pwd(char key[CLEAR_PASSWD_LEN+1],
+ char salt[3],
+ char passwd[CRYPTED_PASSWD_LEN+1])
{
int n;
- /* get encrypted password */
+ /* select a salt, if not already given */
if (salt[0] == '\0')
{
srand(time(NULL));
salt[1] = n;
salt[2] = '\0';
}
+
+ /* get encrypted password */
strcpy(passwd, crypt(key, salt));
+#ifdef PG_PASSWD_DEBUG
/* show it */
-
- /*
- * fprintf(stderr, "key = %s, salt = %s, password = %s\n", key, salt,
- * passwd);
- */
-}
-
-#ifdef NOT_USED
-static int
-check_pwd(char key[9], char passwd[PG_PASSWD_LEN + 1])
-{
- char shouldbe[PG_PASSWD_LEN + 1];
- char salt[3];
-
- salt[0] = passwd[0];
- salt[1] = passwd[1];
- salt[2] = '\0';
- encrypt_pwd(key, salt, shouldbe);
-
- return strncmp(shouldbe, passwd, PG_PASSWD_LEN) == 0 ? 1 : 0;
-}
-
+ fprintf(stderr, "key = %s, salt = %s, password = %s\n",
+ key, salt, passwd);
#endif
+}
static void
prompt_for_username(char *username)
printf("Username: ");
fflush(stdout);
- if (fgets(username, 9, stdin) == NULL)
+ if (fgets(username, NAMEDATALEN, stdin) == NULL)
username[0] = '\0';
length = strlen(username);
#endif
- printf(prompt);
- fflush(stdout);
#ifdef HAVE_TERMIOS_H
tcgetattr(0, &t);
t_orig = t;
t.c_lflag &= ~ECHO;
tcsetattr(0, TCSADRAIN, &t);
#endif
- if (fgets(password, 9, stdin) == NULL)
+
+ printf(prompt);
+ fflush(stdout);
+
+ if (fgets(password, CLEAR_PASSWD_LEN+1, stdin) == NULL)
password[0] = '\0';
+
#ifdef HAVE_TERMIOS_H
tcsetattr(0, TCSADRAIN, &t_orig);
#endif
int
main(int argc, char *argv[])
{
- static char bkname[MAXPGPATH];
char *filename;
- char username[9];
+ char bkname[MAXPGPATH];
+ char username[NAMEDATALEN];
char salt[3];
- char key[9],
- key2[9];
- char e_passwd[PG_PASSWD_LEN + 1];
+ char key[CLEAR_PASSWD_LEN + 1],
+ key2[CLEAR_PASSWD_LEN + 1];
+ char e_passwd[CRYPTED_PASSWD_LEN + 1];
int i;
progname = argv[0];
prompt_for_username(username);
prompt_for_password("New password: ", key);
prompt_for_password("Re-enter new password: ", key2);
- if (strncmp(key, key2, 8) != 0)
+ if (strcmp(key, key2) != 0)
{
fprintf(stderr, "Password mismatch\n");
exit(1);
{ /* did not exist */
if (npwds == MAXPWDS)
{
- fprintf(stderr, "Cannot handle so may entries\n");
+ fprintf(stderr, "Cannot handle so many entries\n");
exit(1);
}
pwds[npwds].uname = strdup(username);