1
1
/*-------------------------------------------------------------------------
2
2
*
3
3
* crypt.c
4
- * Look into the password file and check the encrypted password with
5
- * the one passed in from the frontend.
4
+ * Set of routines to look into the password file and check the
5
+ * encrypted password with the one passed in from the frontend.
6
6
*
7
7
* Original coding by Todd A. Brandys
8
8
*
30
30
31
31
32
32
/*
33
- * Check given password for given user, and return STATUS_OK or STATUS_ERROR.
34
- * In the error case, optionally store a palloc'd string at *logdetail
35
- * that will be sent to the postmaster log (but not the client).
33
+ * Fetch information of a given role necessary to check password data,
34
+ * and return STATUS_OK or STATUS_ERROR. In the case of an error,
35
+ * optionally store a palloc'd string at *logdetail that will be sent
36
+ * to the postmaster log (but not the client).
36
37
*/
37
38
int
38
- md5_crypt_verify (const Port * port , const char * role , char * client_pass ,
39
+ get_role_details (const char * role ,
40
+ char * * password ,
41
+ TimestampTz * vuntil ,
42
+ bool * vuntil_null ,
39
43
char * * logdetail )
40
44
{
41
- int retval = STATUS_ERROR ;
42
- char * shadow_pass ,
43
- * crypt_pwd ;
44
- TimestampTz vuntil = 0 ;
45
- char * crypt_client_pass = client_pass ;
46
45
HeapTuple roleTup ;
47
46
Datum datum ;
48
47
bool isnull ;
49
48
49
+ * vuntil = 0 ;
50
+ * vuntil_null = true;
51
+
50
52
/* Get role info from pg_authid */
51
53
roleTup = SearchSysCache1 (AUTHNAME , PointerGetDatum (role ));
52
54
if (!HeapTupleIsValid (roleTup ))
@@ -65,22 +67,49 @@ md5_crypt_verify(const Port *port, const char *role, char *client_pass,
65
67
role );
66
68
return STATUS_ERROR ; /* user has no password */
67
69
}
68
- shadow_pass = TextDatumGetCString (datum );
70
+ * password = TextDatumGetCString (datum );
69
71
70
72
datum = SysCacheGetAttr (AUTHNAME , roleTup ,
71
73
Anum_pg_authid_rolvaliduntil , & isnull );
72
74
if (!isnull )
73
- vuntil = DatumGetTimestampTz (datum );
75
+ {
76
+ * vuntil = DatumGetTimestampTz (datum );
77
+ * vuntil_null = false;
78
+ }
74
79
75
80
ReleaseSysCache (roleTup );
76
81
77
- if (* shadow_pass == '\0' )
82
+ if (* * password == '\0' )
78
83
{
79
84
* logdetail = psprintf (_ ("User \"%s\" has an empty password." ),
80
85
role );
81
86
return STATUS_ERROR ; /* empty password */
82
87
}
83
88
89
+ return STATUS_OK ;
90
+ }
91
+
92
+ /*
93
+ * Check given password for given user, and return STATUS_OK or STATUS_ERROR.
94
+ * In the error case, optionally store a palloc'd string at *logdetail
95
+ * that will be sent to the postmaster log (but not the client).
96
+ */
97
+ int
98
+ md5_crypt_verify (const Port * port , const char * role , char * client_pass ,
99
+ char * * logdetail )
100
+ {
101
+ int retval = STATUS_ERROR ;
102
+ char * shadow_pass ,
103
+ * crypt_pwd ;
104
+ TimestampTz vuntil ;
105
+ char * crypt_client_pass = client_pass ;
106
+ bool vuntil_null ;
107
+
108
+ /* fetch details about role needed for password checks */
109
+ if (get_role_details (role , & shadow_pass , & vuntil , & vuntil_null ,
110
+ logdetail ) != STATUS_OK )
111
+ return STATUS_ERROR ;
112
+
84
113
/*
85
114
* Compare with the encrypted or plain password depending on the
86
115
* authentication method being used for this connection. (We do not
@@ -152,7 +181,7 @@ md5_crypt_verify(const Port *port, const char *role, char *client_pass,
152
181
/*
153
182
* Password OK, now check to be sure we are not past rolvaliduntil
154
183
*/
155
- if (isnull )
184
+ if (vuntil_null )
156
185
retval = STATUS_OK ;
157
186
else if (vuntil < GetCurrentTimestamp ())
158
187
{
0 commit comments