11/*-------------------------------------------------------------------------
22 *
33 * crypt.c
4- *Look intopg_shadow and check the encrypted password with
5- *the one passed in from the frontend.
4+ * Look intothe password file and check the encrypted password with
5+ * the one passed in from the frontend.
66 *
7- *Modification History
7+ *Original coding by Todd A. Brandys
88 *
9- *Dec 17, 1997 - Todd A. Brandys
10- *Orignal Version Completed.
9+ *Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
10+ * Portions Copyright (c) 1994, Regents of the University of California
1111 *
12- * $Id: crypt.c,v 1.39 2001/10/25 05:49:30 momjian Exp $
12+ * $Header: /cvsroot/pgsql/src/backend/libpq/ crypt.c,v 1.40 2001/11/01 18:10:48 tgl Exp $
1313 *
1414 *-------------------------------------------------------------------------
1515 */
16+ #include "postgres.h"
1617
1718#include <errno.h>
1819#include <unistd.h>
1920
20- #include "postgres.h"
2121#include "libpq/crypt.h"
2222#include "libpq/libpq.h"
2323#include "miscadmin.h"
@@ -82,45 +82,45 @@ crypt_openpwdfile(void)
8282pwdfile = AllocateFile (filename ,"r" );
8383
8484if (pwdfile == NULL && errno != ENOENT )
85- elog (DEBUG ,"could not open %s: %s " ,filename , strerror ( errno ) );
85+ elog (DEBUG ,"could not open %s: %m " ,filename );
8686
8787pfree (filename );
8888
8989return pwdfile ;
9090}
9191
92- /*-------------------------------------------------------------------------*/
93-
92+ /*
93+ * Compare two password-file lines on the basis of their usernames.
94+ *
95+ * Can also be used to compare just a username against a password-file
96+ * line (for bsearch).
97+ */
9498static int
9599compar_user (const void * user_a ,const void * user_b )
96100{
97-
98- int min ,
99- value ;
100101char * login_a ;
101102char * login_b ;
103+ int len_a ,
104+ len_b ,
105+ result ;
102106
103107login_a = * ((char * * )user_a );
104108login_b = * ((char * * )user_b );
105109
106110/*
107- * We only really want to compare the user logins which are first.We
108- * look for the first SEPSTR char getting the number of chars there
109- * are before it. We only need to compare to the min count from the
110- * two strings.
111+ * We only really want to compare the user logins which are first
112+ * and are terminated by CRYPT_PWD_FILE_SEPSTR. (NB: this code
113+ * effectively assumes that CRYPT_PWD_FILE_SEPSTR is just one char.)
111114 */
112- min = strcspn (login_a ,CRYPT_PWD_FILE_SEPSTR );
113- value = strcspn (login_b ,CRYPT_PWD_FILE_SEPSTR );
114- if (value < min )
115- min = value ;
115+ len_a = strcspn (login_a ,CRYPT_PWD_FILE_SEPSTR );
116+ len_b = strcspn (login_b ,CRYPT_PWD_FILE_SEPSTR );
116117
117- /*
118- * We add one to min so that the separator character is included in
119- * the comparison.Why? I believe this will prevent logins that are
120- * proper prefixes of other logins from being 'masked out'. Being
121- * conservative!
122- */
123- return strncmp (login_a ,login_b ,min + 1 );
118+ result = strncmp (login_a ,login_b ,Min (len_a ,len_b ));
119+
120+ if (result == 0 )/* one could be a prefix of the other */
121+ result = (len_a - len_b );
122+
123+ return result ;
124124}
125125
126126/*-------------------------------------------------------------------------*/
@@ -131,7 +131,7 @@ crypt_loadpwdfile(void)
131131char * filename ;
132132int result ;
133133FILE * pwd_file ;
134- char buffer [256 ];
134+ char buffer [1024 ];
135135
136136filename = crypt_getpwdreloadfilename ();
137137result = unlink (filename );
@@ -145,9 +145,9 @@ crypt_loadpwdfile(void)
145145 */
146146if (!pwd_cache || result == 0 )
147147{
148+ /* free the old data only if this is a reload */
148149if (pwd_cache )
149- {/* free the old data only if this is a
150- * reload */
150+ {
151151while (pwd_cache_count -- )
152152free ((void * )pwd_cache [pwd_cache_count ]);
153153free ((void * )pwd_cache );
@@ -161,7 +161,7 @@ crypt_loadpwdfile(void)
161161/*
162162 * Here is where we load the data from pg_pwd.
163163 */
164- while (fgets (buffer ,256 ,pwd_file )!= NULL )
164+ while (fgets (buffer ,sizeof ( buffer ) ,pwd_file )!= NULL )
165165{
166166/*
167167 * We must remove the return char at the end of the string, as
@@ -170,7 +170,9 @@ crypt_loadpwdfile(void)
170170if (buffer [(result = strlen (buffer )- 1 )]== '\n' )
171171buffer [result ]= '\0' ;
172172
173- pwd_cache = (char * * )realloc ((void * )pwd_cache ,sizeof (char * )* (pwd_cache_count + 1 ));
173+ pwd_cache = (char * * )
174+ realloc ((void * )pwd_cache ,
175+ sizeof (char * )* (pwd_cache_count + 1 ));
174176pwd_cache [pwd_cache_count ++ ]= strdup (buffer );
175177}
176178FreeFile (pwd_file );
@@ -187,7 +189,6 @@ crypt_loadpwdfile(void)
187189static void
188190crypt_parsepwdentry (char * buffer ,char * * pwd ,char * * valdate )
189191{
190-
191192char * parse = buffer ;
192193int count ,
193194i ;
@@ -208,7 +209,7 @@ crypt_parsepwdentry(char *buffer, char **pwd, char **valdate)
208209parse += (count + 1 );
209210
210211/*
211- * store a copy of date login becomes invalid
212+ * store a copy ofthe date login becomes invalid
212213 */
213214count = strcspn (parse ,CRYPT_PWD_FILE_SEPSTR );
214215* valdate = (char * )palloc (count + 1 );
@@ -222,32 +223,26 @@ crypt_parsepwdentry(char *buffer, char **pwd, char **valdate)
222223static int
223224crypt_getloginfo (const char * user ,char * * passwd ,char * * valuntil )
224225{
225- char * pwd ,
226- * valdate ;
227- void * fakeout ;
228-
229- * passwd = NULL ;
230- * valuntil = NULL ;
231226crypt_loadpwdfile ();
232227
233228if (pwd_cache )
234229{
235230char * * pwd_entry ;
236- char user_search [NAMEDATALEN + 2 ];
237231
238- snprintf (user_search ,NAMEDATALEN + 2 ,"%s\t" ,user );
239- fakeout = (void * )& user_search ;
240- if ((pwd_entry = (char * * )bsearch ((void * )& fakeout , (void * )pwd_cache ,pwd_cache_count ,sizeof (char * ),compar_user )))
232+ pwd_entry = (char * * )bsearch ((void * )& user ,
233+ (void * )pwd_cache ,
234+ pwd_cache_count ,
235+ sizeof (char * ),
236+ compar_user );
237+ if (pwd_entry )
241238{
242- crypt_parsepwdentry (* pwd_entry ,& pwd ,& valdate );
243- * passwd = pwd ;
244- * valuntil = valdate ;
239+ crypt_parsepwdentry (* pwd_entry ,passwd ,valuntil );
245240return STATUS_OK ;
246241}
247-
248- return STATUS_OK ;
249242}
250243
244+ * passwd = NULL ;
245+ * valuntil = NULL ;
251246return STATUS_ERROR ;
252247}
253248
@@ -256,23 +251,20 @@ crypt_getloginfo(const char *user, char **passwd, char **valuntil)
256251int
257252md5_crypt_verify (const Port * port ,const char * user ,const char * pgpass )
258253{
259-
260254char * passwd ,
261255* valuntil ,
262256* crypt_pwd ;
263257int retval = STATUS_ERROR ;
264- AbsoluteTime vuntil ,
265- current ;
266258
267259if (crypt_getloginfo (user ,& passwd ,& valuntil )== STATUS_ERROR )
268260return STATUS_ERROR ;
269261
270262if (passwd == NULL || * passwd == '\0' )
271263{
272264if (passwd )
273- pfree (( void * ) passwd );
265+ pfree (passwd );
274266if (valuntil )
275- pfree (( void * ) valuntil );
267+ pfree (valuntil );
276268return STATUS_ERROR ;
277269}
278270
@@ -342,8 +334,11 @@ md5_crypt_verify(const Port *port, const char *user, const char *pgpass)
342334if (strcmp (pgpass ,crypt_pwd )== 0 )
343335{
344336/*
345- *check here to be sure we are not past valuntil
337+ *Password OK, now check to be sure we are not past valuntil
346338 */
339+ AbsoluteTime vuntil ,
340+ current ;
341+
347342if (!valuntil || strcmp (valuntil ,"\\N" )== 0 )
348343vuntil = INVALID_ABSTIME ;
349344else