|
9 | 9 | * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
|
10 | 10 | * Portions Copyright (c) 1994, Regents of the University of California
|
11 | 11 | *
|
12 |
| - * $PostgreSQL: pgsql/src/backend/libpq/crypt.c,v 1.77 2009/01/01 17:23:42 momjian Exp $ |
| 12 | + * $PostgreSQL: pgsql/src/backend/libpq/crypt.c,v 1.78 2009/08/29 19:26:51 tgl Exp $ |
13 | 13 | *
|
14 | 14 | *-------------------------------------------------------------------------
|
15 | 15 | */
|
|
20 | 20 | #include <crypt.h>
|
21 | 21 | #endif
|
22 | 22 |
|
| 23 | +#include "catalog/pg_authid.h" |
23 | 24 | #include "libpq/crypt.h"
|
24 | 25 | #include "libpq/md5.h"
|
| 26 | +#include "miscadmin.h" |
| 27 | +#include "utils/builtins.h" |
| 28 | +#include "utils/syscache.h" |
25 | 29 |
|
26 | 30 |
|
27 | 31 | int
|
28 | 32 | md5_crypt_verify(const Port *port, const char *role, char *client_pass)
|
29 | 33 | {
|
30 |
| - char *shadow_pass = NULL, |
31 |
| - *valuntil = NULL, |
32 |
| - *crypt_pwd; |
33 | 34 | int retval = STATUS_ERROR;
|
34 |
| - List **line; |
35 |
| - ListCell *token; |
| 35 | + char *shadow_pass, |
| 36 | + *crypt_pwd; |
| 37 | + TimestampTz vuntil = 0; |
36 | 38 | char *crypt_client_pass = client_pass;
|
| 39 | + HeapTuple roleTup; |
| 40 | + Datum datum; |
| 41 | + bool isnull; |
| 42 | + |
| 43 | + /* |
| 44 | + * Disable immediate interrupts while doing database access. (Note |
| 45 | + * we don't bother to turn this back on if we hit one of the failure |
| 46 | + * conditions, since we can expect we'll just exit right away anyway.) |
| 47 | + */ |
| 48 | + ImmediateInterruptOK = false; |
37 | 49 |
|
38 |
| - if ((line = get_role_line(role)) == NULL) |
39 |
| - return STATUS_ERROR; |
| 50 | + /* Get role info from pg_authid */ |
| 51 | + roleTup = SearchSysCache(AUTHNAME, |
| 52 | + PointerGetDatum(role), |
| 53 | + 0, 0, 0); |
| 54 | + if (!HeapTupleIsValid(roleTup)) |
| 55 | + return STATUS_ERROR; /* no such user */ |
40 | 56 |
|
41 |
| - /* Skip over rolename */ |
42 |
| - token = list_head(*line); |
43 |
| - if (token) |
44 |
| - token = lnext(token); |
45 |
| - if (token) |
| 57 | + datum = SysCacheGetAttr(AUTHNAME, roleTup, |
| 58 | + Anum_pg_authid_rolpassword, &isnull); |
| 59 | + if (isnull) |
46 | 60 | {
|
47 |
| - shadow_pass = (char *) lfirst(token); |
48 |
| - token = lnext(token); |
49 |
| - if (token) |
50 |
| - valuntil = (char *) lfirst(token); |
| 61 | + ReleaseSysCache(roleTup); |
| 62 | + return STATUS_ERROR; /* user has no password */ |
51 | 63 | }
|
| 64 | + shadow_pass = TextDatumGetCString(datum); |
| 65 | + |
| 66 | + datum = SysCacheGetAttr(AUTHNAME, roleTup, |
| 67 | + Anum_pg_authid_rolvaliduntil, &isnull); |
| 68 | + if (!isnull) |
| 69 | + vuntil = DatumGetTimestampTz(datum); |
52 | 70 |
|
53 |
| - if (shadow_pass == NULL || *shadow_pass == '\0') |
54 |
| - return STATUS_ERROR; |
| 71 | + ReleaseSysCache(roleTup); |
| 72 | + |
| 73 | + if (*shadow_pass == '\0') |
| 74 | + return STATUS_ERROR; /* empty password */ |
| 75 | + |
| 76 | + /* Re-enable immediate response to SIGTERM/SIGINT/timeout interrupts */ |
| 77 | + ImmediateInterruptOK = true; |
| 78 | + /* And don't forget to detect one that already arrived */ |
| 79 | + CHECK_FOR_INTERRUPTS(); |
55 | 80 |
|
56 | 81 | /*
|
57 | 82 | * Compare with the encrypted or plain password depending on the
|
@@ -119,24 +144,14 @@ md5_crypt_verify(const Port *port, const char *role, char *client_pass)
|
119 | 144 | if (strcmp(crypt_client_pass, crypt_pwd) == 0)
|
120 | 145 | {
|
121 | 146 | /*
|
122 |
| - * Password OK, now check to be sure we are not past valuntil |
| 147 | + * Password OK, now check to be sure we are not past rolvaliduntil |
123 | 148 | */
|
124 |
| - if (valuntil == NULL || *valuntil == '\0') |
| 149 | + if (isnull) |
125 | 150 | retval = STATUS_OK;
|
| 151 | + else if (vuntil < GetCurrentTimestamp()) |
| 152 | + retval = STATUS_ERROR; |
126 | 153 | else
|
127 |
| - { |
128 |
| - TimestampTz vuntil; |
129 |
| - |
130 |
| - vuntil = DatumGetTimestampTz(DirectFunctionCall3(timestamptz_in, |
131 |
| - CStringGetDatum(valuntil), |
132 |
| - ObjectIdGetDatum(InvalidOid), |
133 |
| - Int32GetDatum(-1))); |
134 |
| - |
135 |
| - if (vuntil < GetCurrentTimestamp()) |
136 |
| - retval = STATUS_ERROR; |
137 |
| - else |
138 |
| - retval = STATUS_OK; |
139 |
| - } |
| 154 | + retval = STATUS_OK; |
140 | 155 | }
|
141 | 156 |
|
142 | 157 | if (port->hba->auth_method == uaMD5)
|
|
0 commit comments