aboutsummaryrefslogtreecommitdiffstats
path: root/databases/postgresql-devel/files/patch-aj
blob: 94c0d6d7999131936d1806167691c6163799c3c0 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
--- 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 <errno.h>
 #include <time.h>
 #include <ctype.h>
+
+#if defined(__FreeBSD__)
+#include <pwd.h>  /* defines _PASSWORD_LEN, max # of characters in a password */
+#include <sys/time.h> /* 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 <pgsql-bugs@postgresql.org>.\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];