summaryrefslogtreecommitdiff
path: root/auth-pam.c
diff options
context:
space:
mode:
Diffstat (limited to 'auth-pam.c')
-rw-r--r--auth-pam.c140
1 files changed, 82 insertions, 58 deletions
diff --git a/auth-pam.c b/auth-pam.c
index 147f4f8bb..6ce8c429b 100644
--- a/auth-pam.c
+++ b/auth-pam.c
@@ -47,7 +47,7 @@
47 47
48/* Based on $FreeBSD: src/crypto/openssh/auth2-pam-freebsd.c,v 1.11 2003/03/31 13:48:18 des Exp $ */ 48/* Based on $FreeBSD: src/crypto/openssh/auth2-pam-freebsd.c,v 1.11 2003/03/31 13:48:18 des Exp $ */
49#include "includes.h" 49#include "includes.h"
50RCSID("$Id: auth-pam.c,v 1.114 2004/08/16 13:12:06 dtucker Exp $"); 50RCSID("$Id: auth-pam.c,v 1.121 2005/01/20 02:29:51 dtucker Exp $");
51 51
52#ifdef USE_PAM 52#ifdef USE_PAM
53#if defined(HAVE_SECURITY_PAM_APPL_H) 53#if defined(HAVE_SECURITY_PAM_APPL_H)
@@ -185,8 +185,8 @@ static int sshpam_cred_established = 0;
185static int sshpam_account_status = -1; 185static int sshpam_account_status = -1;
186static char **sshpam_env = NULL; 186static char **sshpam_env = NULL;
187static Authctxt *sshpam_authctxt = NULL; 187static Authctxt *sshpam_authctxt = NULL;
188static char badpw[] = "\b\n\r\177INCORRECT";
189static const char *sshpam_password = NULL; 188static const char *sshpam_password = NULL;
189static char badpw[] = "\b\n\r\177INCORRECT";
190 190
191/* Some PAM implementations don't implement this */ 191/* Some PAM implementations don't implement this */
192#ifndef HAVE_PAM_GETENVLIST 192#ifndef HAVE_PAM_GETENVLIST
@@ -491,6 +491,51 @@ sshpam_null_conv(int n, struct pam_message **msg,
491 491
492static struct pam_conv null_conv = { sshpam_null_conv, NULL }; 492static struct pam_conv null_conv = { sshpam_null_conv, NULL };
493 493
494static int
495sshpam_store_conv(int n, struct pam_message **msg,
496 struct pam_response **resp, void *data)
497{
498 struct pam_response *reply;
499 int i;
500 size_t len;
501
502 debug3("PAM: %s called with %d messages", __func__, n);
503 *resp = NULL;
504
505 if (n <= 0 || n > PAM_MAX_NUM_MSG)
506 return (PAM_CONV_ERR);
507
508 if ((reply = malloc(n * sizeof(*reply))) == NULL)
509 return (PAM_CONV_ERR);
510 memset(reply, 0, n * sizeof(*reply));
511
512 for (i = 0; i < n; ++i) {
513 switch (PAM_MSG_MEMBER(msg, i, msg_style)) {
514 case PAM_ERROR_MSG:
515 case PAM_TEXT_INFO:
516 len = strlen(PAM_MSG_MEMBER(msg, i, msg));
517 buffer_append(&loginmsg, PAM_MSG_MEMBER(msg, i, msg), len);
518 buffer_append(&loginmsg, "\n", 1 );
519 reply[i].resp_retcode = PAM_SUCCESS;
520 break;
521 default:
522 goto fail;
523 }
524 }
525 *resp = reply;
526 return (PAM_SUCCESS);
527
528 fail:
529 for(i = 0; i < n; i++) {
530 if (reply[i].resp != NULL)
531 xfree(reply[i].resp);
532 }
533 xfree(reply);
534 return (PAM_CONV_ERR);
535}
536
537static struct pam_conv store_conv = { sshpam_store_conv, NULL };
538
494void 539void
495sshpam_cleanup(void) 540sshpam_cleanup(void)
496{ 541{
@@ -528,7 +573,7 @@ sshpam_init(Authctxt *authctxt)
528 } 573 }
529 debug("PAM: initializing for \"%s\"", user); 574 debug("PAM: initializing for \"%s\"", user);
530 sshpam_err = 575 sshpam_err =
531 pam_start(SSHD_PAM_SERVICE, user, &null_conv, &sshpam_handle); 576 pam_start(SSHD_PAM_SERVICE, user, &store_conv, &sshpam_handle);
532 sshpam_authctxt = authctxt; 577 sshpam_authctxt = authctxt;
533 578
534 if (sshpam_err != PAM_SUCCESS) { 579 if (sshpam_err != PAM_SUCCESS) {
@@ -610,7 +655,7 @@ sshpam_query(void *ctx, char **name, char **info,
610 size_t plen; 655 size_t plen;
611 u_char type; 656 u_char type;
612 char *msg; 657 char *msg;
613 size_t len; 658 size_t len, mlen;
614 659
615 debug3("PAM: %s entering", __func__); 660 debug3("PAM: %s entering", __func__);
616 buffer_init(&buffer); 661 buffer_init(&buffer);
@@ -623,22 +668,27 @@ sshpam_query(void *ctx, char **name, char **info,
623 while (ssh_msg_recv(ctxt->pam_psock, &buffer) == 0) { 668 while (ssh_msg_recv(ctxt->pam_psock, &buffer) == 0) {
624 type = buffer_get_char(&buffer); 669 type = buffer_get_char(&buffer);
625 msg = buffer_get_string(&buffer, NULL); 670 msg = buffer_get_string(&buffer, NULL);
671 mlen = strlen(msg);
626 switch (type) { 672 switch (type) {
627 case PAM_PROMPT_ECHO_ON: 673 case PAM_PROMPT_ECHO_ON:
628 case PAM_PROMPT_ECHO_OFF: 674 case PAM_PROMPT_ECHO_OFF:
629 *num = 1; 675 *num = 1;
630 len = plen + strlen(msg) + 1; 676 len = plen + mlen + 1;
631 **prompts = xrealloc(**prompts, len); 677 **prompts = xrealloc(**prompts, len);
632 plen += snprintf(**prompts + plen, len, "%s", msg); 678 strlcpy(**prompts + plen, msg, len - plen);
679 plen += mlen;
633 **echo_on = (type == PAM_PROMPT_ECHO_ON); 680 **echo_on = (type == PAM_PROMPT_ECHO_ON);
634 xfree(msg); 681 xfree(msg);
635 return (0); 682 return (0);
636 case PAM_ERROR_MSG: 683 case PAM_ERROR_MSG:
637 case PAM_TEXT_INFO: 684 case PAM_TEXT_INFO:
638 /* accumulate messages */ 685 /* accumulate messages */
639 len = plen + strlen(msg) + 2; 686 len = plen + mlen + 2;
640 **prompts = xrealloc(**prompts, len); 687 **prompts = xrealloc(**prompts, len);
641 plen += snprintf(**prompts + plen, len, "%s\n", msg); 688 strlcpy(**prompts + plen, msg, len - plen);
689 plen += mlen;
690 strlcat(**prompts + plen, "\n", len - plen);
691 plen++;
642 xfree(msg); 692 xfree(msg);
643 break; 693 break;
644 case PAM_SUCCESS: 694 case PAM_SUCCESS:
@@ -652,6 +702,12 @@ sshpam_query(void *ctx, char **name, char **info,
652 **prompts = NULL; 702 **prompts = NULL;
653 } 703 }
654 if (type == PAM_SUCCESS) { 704 if (type == PAM_SUCCESS) {
705 if (!sshpam_authctxt->valid ||
706 (sshpam_authctxt->pw->pw_uid == 0 &&
707 options.permit_root_login != PERMIT_YES))
708 fatal("Internal error: PAM auth "
709 "succeeded when it should have "
710 "failed");
655 import_environments(&buffer); 711 import_environments(&buffer);
656 *num = 0; 712 *num = 0;
657 **echo_on = 0; 713 **echo_on = 0;
@@ -765,11 +821,13 @@ finish_pam(void)
765u_int 821u_int
766do_pam_account(void) 822do_pam_account(void)
767{ 823{
824 debug("%s: called", __func__);
768 if (sshpam_account_status != -1) 825 if (sshpam_account_status != -1)
769 return (sshpam_account_status); 826 return (sshpam_account_status);
770 827
771 sshpam_err = pam_acct_mgmt(sshpam_handle, 0); 828 sshpam_err = pam_acct_mgmt(sshpam_handle, 0);
772 debug3("PAM: %s pam_acct_mgmt = %d", __func__, sshpam_err); 829 debug3("PAM: %s pam_acct_mgmt = %d (%s)", __func__, sshpam_err,
830 pam_strerror(sshpam_handle, sshpam_err));
773 831
774 if (sshpam_err != PAM_SUCCESS && sshpam_err != PAM_NEW_AUTHTOK_REQD) { 832 if (sshpam_err != PAM_SUCCESS && sshpam_err != PAM_NEW_AUTHTOK_REQD) {
775 sshpam_account_status = 0; 833 sshpam_account_status = 0;
@@ -799,7 +857,7 @@ void
799do_pam_setcred(int init) 857do_pam_setcred(int init)
800{ 858{
801 sshpam_err = pam_set_item(sshpam_handle, PAM_CONV, 859 sshpam_err = pam_set_item(sshpam_handle, PAM_CONV,
802 (const void *)&null_conv); 860 (const void *)&store_conv);
803 if (sshpam_err != PAM_SUCCESS) 861 if (sshpam_err != PAM_SUCCESS)
804 fatal("PAM: failed to set PAM_CONV: %s", 862 fatal("PAM: failed to set PAM_CONV: %s",
805 pam_strerror(sshpam_handle, sshpam_err)); 863 pam_strerror(sshpam_handle, sshpam_err));
@@ -900,51 +958,6 @@ do_pam_chauthtok(void)
900 pam_strerror(sshpam_handle, sshpam_err)); 958 pam_strerror(sshpam_handle, sshpam_err));
901} 959}
902 960
903static int
904sshpam_store_conv(int n, struct pam_message **msg,
905 struct pam_response **resp, void *data)
906{
907 struct pam_response *reply;
908 int i;
909 size_t len;
910
911 debug3("PAM: %s called with %d messages", __func__, n);
912 *resp = NULL;
913
914 if (n <= 0 || n > PAM_MAX_NUM_MSG)
915 return (PAM_CONV_ERR);
916
917 if ((reply = malloc(n * sizeof(*reply))) == NULL)
918 return (PAM_CONV_ERR);
919 memset(reply, 0, n * sizeof(*reply));
920
921 for (i = 0; i < n; ++i) {
922 switch (PAM_MSG_MEMBER(msg, i, msg_style)) {
923 case PAM_ERROR_MSG:
924 case PAM_TEXT_INFO:
925 len = strlen(PAM_MSG_MEMBER(msg, i, msg));
926 buffer_append(&loginmsg, PAM_MSG_MEMBER(msg, i, msg), len);
927 buffer_append(&loginmsg, "\n", 1 );
928 reply[i].resp_retcode = PAM_SUCCESS;
929 break;
930 default:
931 goto fail;
932 }
933 }
934 *resp = reply;
935 return (PAM_SUCCESS);
936
937 fail:
938 for(i = 0; i < n; i++) {
939 if (reply[i].resp != NULL)
940 xfree(reply[i].resp);
941 }
942 xfree(reply);
943 return (PAM_CONV_ERR);
944}
945
946static struct pam_conv store_conv = { sshpam_store_conv, NULL };
947
948void 961void
949do_pam_session(void) 962do_pam_session(void)
950{ 963{
@@ -955,10 +968,21 @@ do_pam_session(void)
955 fatal("PAM: failed to set PAM_CONV: %s", 968 fatal("PAM: failed to set PAM_CONV: %s",
956 pam_strerror(sshpam_handle, sshpam_err)); 969 pam_strerror(sshpam_handle, sshpam_err));
957 sshpam_err = pam_open_session(sshpam_handle, 0); 970 sshpam_err = pam_open_session(sshpam_handle, 0);
958 if (sshpam_err != PAM_SUCCESS) 971 if (sshpam_err == PAM_SUCCESS)
959 fatal("PAM: pam_open_session(): %s", 972 sshpam_session_open = 1;
973 else {
974 sshpam_session_open = 0;
975 disable_forwarding();
976 error("PAM: pam_open_session(): %s",
960 pam_strerror(sshpam_handle, sshpam_err)); 977 pam_strerror(sshpam_handle, sshpam_err));
961 sshpam_session_open = 1; 978 }
979
980}
981
982int
983is_pam_session_open(void)
984{
985 return sshpam_session_open;
962} 986}
963 987
964/* 988/*