--- src/bin/pg_passwd/pg_passwd.c.orig Sat Mar 24 01:54:55 2001 +++ src/bin/pg_passwd/pg_passwd.c Wed Apr 18 04:54:14 2001 @@ -7,6 +7,12 @@ #include #include #include + +#if defined(__FreeBSD__) +#include /* defines _PASSWORD_LEN, max # of characters in a password */ +#include /* gettimeofday for password salt */ +#endif + #define issaltchar(c) (isalnum((unsigned char) (c)) || (c) == '.' || (c) == '/') #ifdef HAVE_TERMIOS_H @@ -23,18 +29,31 @@ * We assume that the output of crypt(3) is always 13 characters, * and that at most 8 characters can usefully be sent to it. * + * For FreeBSD, take these values from /usr/include/pwd.h * Postgres usernames are assumed to be less than NAMEDATALEN chars long. */ +#if defined(__FreeBSD__) +#define CLEAR_PASSWD_LEN _PASSWORD_LEN +#define CRYPTED_PASSWD_LEN _PASSWORD_LEN /* max length, not containing NULL */ +#define SALT_LEN 10 +#else #define CLEAR_PASSWD_LEN 8 /* not including null */ #define CRYPTED_PASSWD_LEN 13 /* not including null */ +#define SALT_LEN 3 +#endif + +static unsigned char itoa64[] = /* 0 ... 63 => ascii - 64 */ + "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + const char *progname; static void usage(void); +static void to64(char *s, long v, int n); static void read_pwd_file(char *filename); static void write_pwd_file(char *filename, char *bkname); static void encrypt_pwd(char key[CLEAR_PASSWD_LEN + 1], - char salt[3], + char salt[SALT_LEN], char passwd[CRYPTED_PASSWD_LEN + 1]); static void prompt_for_username(char *username); static void prompt_for_password(char *prompt, char *password); @@ -47,6 +66,15 @@ printf("Report bugs to .\n"); } +static void +to64(char *s, long v, int n) +{ + while (--n >= 0) { + *s++ = itoa64[v&0x3f]; + v >>= 6; + } +} + typedef struct { char *uname; @@ -154,7 +182,7 @@ if (q != NULL) *(q++) = '\0'; - if (strlen(p) != CRYPTED_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); @@ -221,15 +249,25 @@ static void encrypt_pwd(char key[CLEAR_PASSWD_LEN + 1], - char salt[3], + char salt[SALT_LEN], char passwd[CRYPTED_PASSWD_LEN + 1]) { +#if !defined(__FreeBSD__) int n; - +#endif /* select a salt, if not already given */ if (salt[0] == '\0') { +#if defined(__FreeBSD__) + struct timeval tv; + srandomdev(); + gettimeofday(&tv,0); + to64(&salt[0], random(), 3); + to64(&salt[3], tv.tv_usec, 3); + to64(&salt[6], tv.tv_sec, 2); + salt[8] = '\0'; srand(time(NULL)); +#else do { n = rand() % 256; @@ -241,6 +279,7 @@ } while (!issaltchar(n)); salt[1] = n; salt[2] = '\0'; +#endif } /* get encrypted password */ @@ -335,7 +374,7 @@ char *filename; char bkname[MAXPGPATH]; char username[NAMEDATALEN]; - char salt[3]; + char salt[SALT_LEN]; char key[CLEAR_PASSWD_LEN + 1], key2[CLEAR_PASSWD_LEN + 1]; char e_passwd[CRYPTED_PASSWD_LEN + 1];