Skip to content

Commit aed378e

Browse files
committed
Fix authentication so that it doesn't record an extra 'Password
authentication failed' and a 'send() failed: Broken pipe' message on every connection from psql in password auth mode. Problem is that psql doesn't ask user for a password until it sees a password challenge failure, and libpq just closes the connection unceremoniously if it's challenged for a password when it hasn't got one to send. Accordingly, EOF from the client after asking for a password is normal behavior and should not result in postmaster log entries.
1 parent 13e467f commit aed378e

File tree

1 file changed

+57
-38
lines changed

1 file changed

+57
-38
lines changed

src/backend/libpq/auth.c

Lines changed: 57 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
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);
3737
static int checkPassword(Port *port, char *user, char *password);
3838
static int old_be_recvauth(Port *port);
3939
static 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);
4141
static int recv_and_check_password_packet(Port *port);
4242
static 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
*/
422426
static 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

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy