88 *
99 *
1010 * IDENTIFICATION
11- * $Header: /cvsroot/pgsql/src/backend/libpq/auth.c,v 1.68 2001/09/26 19:54:12 momjian Exp $
11+ * $Header: /cvsroot/pgsql/src/backend/libpq/auth.c,v 1.69 2001/10/18 22:44:37 tgl Exp $
1212 *
1313 *-------------------------------------------------------------------------
1414 */
@@ -37,7 +37,7 @@ static void sendAuthRequest(Port *port, AuthRequest areq);
3737static int checkPassword (Port * port , char * user , char * password );
3838static int old_be_recvauth (Port * port );
3939static int map_old_to_new (Port * port , UserAuth old , int status );
40- static void auth_failed (Port * port );
40+ static void auth_failed (Port * port , int status );
4141static int recv_and_check_password_packet (Port * port );
4242static int recv_and_check_passwordv0 (Port * port );
4343
@@ -341,17 +341,23 @@ recv_and_check_passwordv0(Port *port)
341341 * password ,
342342 * cp ,
343343 * start ;
344+ int status ;
344345
345- pq_getint (& len , 4 );
346+ if (pq_getint (& len , 4 ) == EOF )
347+ return STATUS_EOF ;
346348 len -= 4 ;
347349 buf = palloc (len );
348- pq_getbytes (buf , len );
350+ if (pq_getbytes (buf , len ) == EOF )
351+ {
352+ pfree (buf );
353+ return STATUS_EOF ;
354+ }
349355
350356 pp = (PasswordPacketV0 * ) buf ;
351357
352358 /*
353359 * The packet is supposed to comprise the user name and the password
354- * as C strings. Be careful the check that this is the case.
360+ * as C strings. Be careful to check that this is the case.
355361 */
356362 user = password = NULL ;
357363
@@ -379,13 +385,10 @@ recv_and_check_passwordv0(Port *port)
379385 "pg_password_recvauth: badly formed password packet.\n" );
380386 fputs (PQerrormsg , stderr );
381387 pqdebug ("%s" , PQerrormsg );
382-
383- pfree (buf );
384- auth_failed (port );
388+ status = STATUS_ERROR ;
385389 }
386390 else
387391 {
388- int status ;
389392 UserAuth saved ;
390393
391394 /* Check the password. */
@@ -395,15 +398,16 @@ recv_and_check_passwordv0(Port *port)
395398
396399 status = checkPassword (port , user , password );
397400
398- pfree (buf );
399401 port -> auth_method = saved ;
400402
401403 /* Adjust the result if necessary. */
402404 if (map_old_to_new (port , uaPassword , status ) != STATUS_OK )
403- auth_failed ( port ) ;
405+ status = STATUS_ERROR ;
404406 }
405407
406- return STATUS_OK ;
408+ pfree (buf );
409+
410+ return status ;
407411}
408412
409413
@@ -420,10 +424,23 @@ recv_and_check_passwordv0(Port *port)
420424 * postmaster log, which we hope is only readable by good guys.
421425 */
422426static void
423- auth_failed (Port * port )
427+ auth_failed (Port * port , int status )
424428{
425429 const char * authmethod = "Unknown auth method:" ;
426430
431+ /*
432+ * If we failed due to EOF from client, just quit; there's no point
433+ * in trying to send a message to the client, and not much point in
434+ * logging the failure in the postmaster log. (Logging the failure
435+ * might be desirable, were it not for the fact that libpq closes the
436+ * connection unceremoniously if challenged for a password when it
437+ * hasn't got one to send. We'll get a useless log entry for
438+ * every psql connection under password auth, even if it's perfectly
439+ * successful, if we log STATUS_EOF events.)
440+ */
441+ if (status == STATUS_EOF )
442+ proc_exit (0 );
443+
427444 switch (port -> auth_method )
428445 {
429446 case uaReject :
@@ -455,6 +472,7 @@ auth_failed(Port *port)
455472
456473 elog (FATAL , "%s authentication failed for user \"%s\"" ,
457474 authmethod , port -> user );
475+ /* doesn't return */
458476}
459477
460478
@@ -477,10 +495,11 @@ ClientAuthentication(Port *port)
477495 elog (FATAL , "Missing or erroneous pg_hba.conf file, see postmaster log for details" );
478496
479497 /* Handle old style authentication. */
480- else if (PG_PROTOCOL_MAJOR (port -> proto ) == 0 )
498+ if (PG_PROTOCOL_MAJOR (port -> proto ) == 0 )
481499 {
482- if (old_be_recvauth (port ) != STATUS_OK )
483- auth_failed (port );
500+ status = old_be_recvauth (port );
501+ if (status != STATUS_OK )
502+ auth_failed (port , status );
484503 return ;
485504 }
486505
@@ -505,9 +524,8 @@ ClientAuthentication(Port *port)
505524 elog (FATAL ,
506525 "No pg_hba.conf entry for host %s, user %s, database %s" ,
507526 hostinfo , port -> user , port -> database );
508- return ;
527+ break ;
509528 }
510- break ;
511529
512530 case uaKrb4 :
513531 sendAuthRequest (port , AUTH_REQ_KRB4 );
@@ -533,11 +551,8 @@ ClientAuthentication(Port *port)
533551 {
534552 int on = 1 ;
535553 if (setsockopt (port -> sock , 0 , LOCAL_CREDS , & on , sizeof (on )) < 0 )
536- {
537554 elog (FATAL ,
538555 "pg_local_sendauth: can't do setsockopt: %s\n" , strerror (errno ));
539- return ;
540- }
541556 }
542557#endif
543558 if (port -> raddr .sa .sa_family == AF_UNIX )
@@ -551,15 +566,16 @@ ClientAuthentication(Port *port)
551566 status = recv_and_check_password_packet (port );
552567 break ;
553568
554- case uaCrypt :
555- sendAuthRequest (port , AUTH_REQ_CRYPT );
556- status = recv_and_check_password_packet (port );
557- break ;
569+ case uaCrypt :
570+ sendAuthRequest (port , AUTH_REQ_CRYPT );
571+ status = recv_and_check_password_packet (port );
572+ break ;
558573
559- case uaPassword :
560- sendAuthRequest (port , AUTH_REQ_PASSWORD );
561- status = recv_and_check_password_packet (port );
562- break ;
574+ case uaPassword :
575+ sendAuthRequest (port , AUTH_REQ_PASSWORD );
576+ status = recv_and_check_password_packet (port );
577+ break ;
578+
563579#ifdef USE_PAM
564580 case uaPAM :
565581 pam_port_cludge = port ;
@@ -575,7 +591,7 @@ ClientAuthentication(Port *port)
575591 if (status == STATUS_OK )
576592 sendAuthRequest (port , AUTH_REQ_OK );
577593 else
578- auth_failed (port );
594+ auth_failed (port , status );
579595}
580596
581597
@@ -654,7 +670,7 @@ pam_passwd_conv_proc (int num_msg, const struct pam_message **msg, struct pam_re
654670
655671 initStringInfo (& buf );
656672 pq_getstr (& buf );
657- if (DebugLvl )
673+ if (DebugLvl > 5 )
658674 fprintf (stderr , "received PAM packet with len=%d, pw=%s\n" ,
659675 len , buf .data );
660676
@@ -786,10 +802,9 @@ CheckPAMAuth(Port *port, char *user, char *password)
786802 }
787803}
788804
789-
790-
791805#endif /* USE_PAM */
792806
807+
793808/*
794809 * Called when we have received the password packet.
795810 */
@@ -801,11 +816,16 @@ recv_and_check_password_packet(Port *port)
801816 int result ;
802817
803818 if (pq_eof () == EOF || pq_getint (& len , 4 ) == EOF )
804- return STATUS_ERROR ; /* client didn't want to send password */
819+ return STATUS_EOF ; /* client didn't want to send password */
820+
805821 initStringInfo (& buf );
806- pq_getstr (& buf ); /* receive password */
822+ if (pq_getstr (& buf ) == EOF ) /* receive password */
823+ {
824+ pfree (buf .data );
825+ return STATUS_EOF ;
826+ }
807827
808- if (DebugLvl )
828+ if (DebugLvl > 5 ) /* this is probably a BAD idea... */
809829 fprintf (stderr , "received password packet with len=%d, pw=%s\n" ,
810830 len , buf .data );
811831
@@ -861,7 +881,7 @@ old_be_recvauth(Port *port)
861881 default :
862882 fprintf (stderr , "Invalid startup message type: %u\n" , msgtype );
863883
864- return STATUS_OK ;
884+ return STATUS_ERROR ;
865885 }
866886
867887 return status ;
@@ -914,4 +934,3 @@ map_old_to_new(Port *port, UserAuth old, int status)
914934
915935 return status ;
916936}
917-
0 commit comments