8
8
*
9
9
*
10
10
* 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 $
12
12
*
13
13
*-------------------------------------------------------------------------
14
14
*/
@@ -37,7 +37,7 @@ static void sendAuthRequest(Port *port, AuthRequest areq);
37
37
static int checkPassword (Port * port , char * user , char * password );
38
38
static int old_be_recvauth (Port * port );
39
39
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 );
41
41
static int recv_and_check_password_packet (Port * port );
42
42
static int recv_and_check_passwordv0 (Port * port );
43
43
@@ -341,17 +341,23 @@ recv_and_check_passwordv0(Port *port)
341
341
* password ,
342
342
* cp ,
343
343
* start ;
344
+ int status ;
344
345
345
- pq_getint (& len , 4 );
346
+ if (pq_getint (& len , 4 ) == EOF )
347
+ return STATUS_EOF ;
346
348
len -= 4 ;
347
349
buf = palloc (len );
348
- pq_getbytes (buf , len );
350
+ if (pq_getbytes (buf , len ) == EOF )
351
+ {
352
+ pfree (buf );
353
+ return STATUS_EOF ;
354
+ }
349
355
350
356
pp = (PasswordPacketV0 * ) buf ;
351
357
352
358
/*
353
359
* 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.
355
361
*/
356
362
user = password = NULL ;
357
363
@@ -379,13 +385,10 @@ recv_and_check_passwordv0(Port *port)
379
385
"pg_password_recvauth: badly formed password packet.\n" );
380
386
fputs (PQerrormsg , stderr );
381
387
pqdebug ("%s" , PQerrormsg );
382
-
383
- pfree (buf );
384
- auth_failed (port );
388
+ status = STATUS_ERROR ;
385
389
}
386
390
else
387
391
{
388
- int status ;
389
392
UserAuth saved ;
390
393
391
394
/* Check the password. */
@@ -395,15 +398,16 @@ recv_and_check_passwordv0(Port *port)
395
398
396
399
status = checkPassword (port , user , password );
397
400
398
- pfree (buf );
399
401
port -> auth_method = saved ;
400
402
401
403
/* Adjust the result if necessary. */
402
404
if (map_old_to_new (port , uaPassword , status ) != STATUS_OK )
403
- auth_failed ( port ) ;
405
+ status = STATUS_ERROR ;
404
406
}
405
407
406
- return STATUS_OK ;
408
+ pfree (buf );
409
+
410
+ return status ;
407
411
}
408
412
409
413
@@ -420,10 +424,23 @@ recv_and_check_passwordv0(Port *port)
420
424
* postmaster log, which we hope is only readable by good guys.
421
425
*/
422
426
static void
423
- auth_failed (Port * port )
427
+ auth_failed (Port * port , int status )
424
428
{
425
429
const char * authmethod = "Unknown auth method:" ;
426
430
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
+
427
444
switch (port -> auth_method )
428
445
{
429
446
case uaReject :
@@ -455,6 +472,7 @@ auth_failed(Port *port)
455
472
456
473
elog (FATAL , "%s authentication failed for user \"%s\"" ,
457
474
authmethod , port -> user );
475
+ /* doesn't return */
458
476
}
459
477
460
478
@@ -477,10 +495,11 @@ ClientAuthentication(Port *port)
477
495
elog (FATAL , "Missing or erroneous pg_hba.conf file, see postmaster log for details" );
478
496
479
497
/* Handle old style authentication. */
480
- else if (PG_PROTOCOL_MAJOR (port -> proto ) == 0 )
498
+ if (PG_PROTOCOL_MAJOR (port -> proto ) == 0 )
481
499
{
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 );
484
503
return ;
485
504
}
486
505
@@ -505,9 +524,8 @@ ClientAuthentication(Port *port)
505
524
elog (FATAL ,
506
525
"No pg_hba.conf entry for host %s, user %s, database %s" ,
507
526
hostinfo , port -> user , port -> database );
508
- return ;
527
+ break ;
509
528
}
510
- break ;
511
529
512
530
case uaKrb4 :
513
531
sendAuthRequest (port , AUTH_REQ_KRB4 );
@@ -533,11 +551,8 @@ ClientAuthentication(Port *port)
533
551
{
534
552
int on = 1 ;
535
553
if (setsockopt (port -> sock , 0 , LOCAL_CREDS , & on , sizeof (on )) < 0 )
536
- {
537
554
elog (FATAL ,
538
555
"pg_local_sendauth: can't do setsockopt: %s\n" , strerror (errno ));
539
- return ;
540
- }
541
556
}
542
557
#endif
543
558
if (port -> raddr .sa .sa_family == AF_UNIX )
@@ -551,15 +566,16 @@ ClientAuthentication(Port *port)
551
566
status = recv_and_check_password_packet (port );
552
567
break ;
553
568
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 ;
558
573
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
+
563
579
#ifdef USE_PAM
564
580
case uaPAM :
565
581
pam_port_cludge = port ;
@@ -575,7 +591,7 @@ ClientAuthentication(Port *port)
575
591
if (status == STATUS_OK )
576
592
sendAuthRequest (port , AUTH_REQ_OK );
577
593
else
578
- auth_failed (port );
594
+ auth_failed (port , status );
579
595
}
580
596
581
597
@@ -654,7 +670,7 @@ pam_passwd_conv_proc (int num_msg, const struct pam_message **msg, struct pam_re
654
670
655
671
initStringInfo (& buf );
656
672
pq_getstr (& buf );
657
- if (DebugLvl )
673
+ if (DebugLvl > 5 )
658
674
fprintf (stderr , "received PAM packet with len=%d, pw=%s\n" ,
659
675
len , buf .data );
660
676
@@ -786,10 +802,9 @@ CheckPAMAuth(Port *port, char *user, char *password)
786
802
}
787
803
}
788
804
789
-
790
-
791
805
#endif /* USE_PAM */
792
806
807
+
793
808
/*
794
809
* Called when we have received the password packet.
795
810
*/
@@ -801,11 +816,16 @@ recv_and_check_password_packet(Port *port)
801
816
int result ;
802
817
803
818
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
+
805
821
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
+ }
807
827
808
- if (DebugLvl )
828
+ if (DebugLvl > 5 ) /* this is probably a BAD idea... */
809
829
fprintf (stderr , "received password packet with len=%d, pw=%s\n" ,
810
830
len , buf .data );
811
831
@@ -861,7 +881,7 @@ old_be_recvauth(Port *port)
861
881
default :
862
882
fprintf (stderr , "Invalid startup message type: %u\n" , msgtype );
863
883
864
- return STATUS_OK ;
884
+ return STATUS_ERROR ;
865
885
}
866
886
867
887
return status ;
@@ -914,4 +934,3 @@ map_old_to_new(Port *port, UserAuth old, int status)
914
934
915
935
return status ;
916
936
}
917
-
0 commit comments