|
Lines 239-244
pthread_join(sp_pthread_t thread, void **value)
Link Here
|
| 239 |
|
239 |
|
| 240 |
|
240 |
|
| 241 |
static pam_handle_t *sshpam_handle = NULL; |
241 |
static pam_handle_t *sshpam_handle = NULL; |
|
|
242 |
static pam_handle_t *sshpam_password_handle = NULL; |
| 242 |
static int sshpam_err = 0; |
243 |
static int sshpam_err = 0; |
| 243 |
static int sshpam_authenticated = 0; |
244 |
static int sshpam_authenticated = 0; |
| 244 |
static int sshpam_session_open = 0; |
245 |
static int sshpam_session_open = 0; |
|
Lines 652-704
static struct pam_conv store_conv = { sshpam_store_conv, NULL };
Link Here
|
| 652 |
void |
653 |
void |
| 653 |
sshpam_cleanup(void) |
654 |
sshpam_cleanup(void) |
| 654 |
{ |
655 |
{ |
| 655 |
if (sshpam_handle == NULL || (use_privsep && !mm_is_monitor())) |
656 |
if (!(sshpam_handle == NULL || (use_privsep && !mm_is_monitor()))) { |
| 656 |
return; |
657 |
debug("PAM: cleanup"); |
| 657 |
debug("PAM: cleanup"); |
658 |
pam_set_item(sshpam_handle, PAM_CONV, (const void *)&null_conv); |
| 658 |
pam_set_item(sshpam_handle, PAM_CONV, (const void *)&null_conv); |
659 |
if (sshpam_session_open) { |
| 659 |
if (sshpam_session_open) { |
660 |
debug("PAM: closing session"); |
| 660 |
debug("PAM: closing session"); |
661 |
pam_close_session(sshpam_handle, PAM_SILENT); |
| 661 |
pam_close_session(sshpam_handle, PAM_SILENT); |
662 |
sshpam_session_open = 0; |
| 662 |
sshpam_session_open = 0; |
663 |
} |
|
|
664 |
if (sshpam_cred_established) { |
| 665 |
debug("PAM: deleting credentials"); |
| 666 |
pam_setcred(sshpam_handle, PAM_DELETE_CRED); |
| 667 |
sshpam_cred_established = 0; |
| 668 |
} |
| 669 |
sshpam_authenticated = 0; |
| 670 |
pam_end(sshpam_handle, sshpam_err); |
| 671 |
sshpam_handle = NULL; |
| 663 |
} |
672 |
} |
| 664 |
if (sshpam_cred_established) { |
673 |
if (!(sshpam_password_handle == NULL)) { |
| 665 |
debug("PAM: deleting credentials"); |
674 |
pam_end(sshpam_password_handle, sshpam_err); |
| 666 |
pam_setcred(sshpam_handle, PAM_DELETE_CRED); |
675 |
sshpam_password_handle = NULL; |
| 667 |
sshpam_cred_established = 0; |
|
|
| 668 |
} |
676 |
} |
| 669 |
sshpam_authenticated = 0; |
|
|
| 670 |
pam_end(sshpam_handle, sshpam_err); |
| 671 |
sshpam_handle = NULL; |
| 672 |
} |
677 |
} |
| 673 |
|
678 |
|
| 674 |
static int |
679 |
static int |
| 675 |
sshpam_init(struct ssh *ssh, Authctxt *authctxt) |
680 |
sshpam_init(struct ssh *ssh, Authctxt *authctxt, char * service_name, pam_handle_t **sshpam_phandle ) |
| 676 |
{ |
681 |
{ |
| 677 |
const char *pam_user, *user = authctxt->user; |
682 |
const char *pam_user, *user = authctxt->user; |
| 678 |
const char **ptr_pam_user = &pam_user; |
683 |
const char **ptr_pam_user = &pam_user; |
|
|
684 |
const char *pam_service; |
| 685 |
const char **ptr_pam_service = &pam_service; |
| 679 |
|
686 |
|
| 680 |
if (sshpam_handle == NULL) { |
687 |
if (*sshpam_phandle == NULL) { |
| 681 |
if (ssh == NULL) { |
688 |
if (ssh == NULL && sshpam_rhost == NULL) { |
| 682 |
fatal("%s: called initially with no " |
689 |
fatal("%s: called initially with no " |
| 683 |
"packet context", __func__); |
690 |
"packet context", __func__); |
| 684 |
} |
691 |
} |
| 685 |
} if (sshpam_handle != NULL) { |
692 |
} |
| 686 |
/* We already have a PAM context; check if the user matches */ |
693 |
if (*sshpam_phandle != NULL) { |
| 687 |
sshpam_err = pam_get_item(sshpam_handle, |
694 |
/* We already have a PAM context; |
|
|
695 |
* check if the user and service name matches */ |
| 696 |
sshpam_err = pam_get_item(*sshpam_phandle, |
| 688 |
PAM_USER, (sshpam_const void **)ptr_pam_user); |
697 |
PAM_USER, (sshpam_const void **)ptr_pam_user); |
| 689 |
if (sshpam_err == PAM_SUCCESS && strcmp(user, pam_user) == 0) |
698 |
if (sshpam_err == PAM_SUCCESS |
| 690 |
return (0); |
699 |
&& strcmp(user, pam_user) == 0 ) { |
| 691 |
pam_end(sshpam_handle, sshpam_err); |
700 |
sshpam_err = pam_get_item(*sshpam_phandle, |
| 692 |
sshpam_handle = NULL; |
701 |
PAM_SERVICE, (sshpam_const void **)ptr_pam_service); |
|
|
702 |
if (sshpam_err == PAM_SUCCESS |
| 703 |
&& strncmp(service_name, pam_service, strlen(service_name)) == 0 ) { |
| 704 |
// full match. no reinit needed. |
| 705 |
return (0); |
| 706 |
} |
| 707 |
} |
| 708 |
/* |
| 709 |
* Clean up previous PAM state. No need to clean up session |
| 710 |
* and creds. |
| 711 |
*/ |
| 712 |
if (sshpam_phandle == &sshpam_handle) { |
| 713 |
/* (This is not needed for password auth, it does not change or read these states) */ |
| 714 |
sshpam_authenticated = 0; |
| 715 |
sshpam_account_status = -1; |
| 716 |
} |
| 717 |
sshpam_err = pam_set_item(sshpam_handle, PAM_CONV, NULL); |
| 718 |
if (sshpam_err != PAM_SUCCESS) |
| 719 |
debug3("Cannot remove PAM conv"); /* a warning only */ |
| 720 |
|
| 721 |
pam_end(*sshpam_phandle, sshpam_err); |
| 722 |
*sshpam_phandle = NULL; |
| 693 |
} |
723 |
} |
| 694 |
debug("PAM: initializing for \"%s\"", user); |
724 |
debug("PAM: (%s) initializing for \"%s\"", service_name, user); |
| 695 |
sshpam_err = |
725 |
sshpam_err = |
| 696 |
pam_start(SSHD_PAM_SERVICE, user, &store_conv, &sshpam_handle); |
726 |
pam_start(service_name, user, &store_conv, sshpam_phandle); |
| 697 |
sshpam_authctxt = authctxt; |
727 |
sshpam_authctxt = authctxt; |
| 698 |
|
728 |
|
| 699 |
if (sshpam_err != PAM_SUCCESS) { |
729 |
if (sshpam_err != PAM_SUCCESS) { |
| 700 |
pam_end(sshpam_handle, sshpam_err); |
730 |
pam_end(*sshpam_phandle, sshpam_err); |
| 701 |
sshpam_handle = NULL; |
731 |
*sshpam_phandle = NULL; |
| 702 |
return (-1); |
732 |
return (-1); |
| 703 |
} |
733 |
} |
| 704 |
|
734 |
|
|
Lines 717-731
sshpam_init(struct ssh *ssh, Authctxt *authctxt)
Link Here
|
| 717 |
} |
747 |
} |
| 718 |
if (sshpam_rhost != NULL) { |
748 |
if (sshpam_rhost != NULL) { |
| 719 |
debug("PAM: setting PAM_RHOST to \"%s\"", sshpam_rhost); |
749 |
debug("PAM: setting PAM_RHOST to \"%s\"", sshpam_rhost); |
| 720 |
sshpam_err = pam_set_item(sshpam_handle, PAM_RHOST, |
750 |
sshpam_err = pam_set_item(*sshpam_phandle, PAM_RHOST, |
| 721 |
sshpam_rhost); |
751 |
sshpam_rhost); |
| 722 |
if (sshpam_err != PAM_SUCCESS) { |
752 |
if (sshpam_err != PAM_SUCCESS) { |
| 723 |
pam_end(sshpam_handle, sshpam_err); |
753 |
pam_end(*sshpam_phandle, sshpam_err); |
| 724 |
sshpam_handle = NULL; |
754 |
*sshpam_phandle = NULL; |
| 725 |
return (-1); |
755 |
return (-1); |
| 726 |
} |
756 |
} |
| 727 |
/* Put SSH_CONNECTION in the PAM environment too */ |
757 |
/* Put SSH_CONNECTION in the PAM environment too */ |
| 728 |
pam_putenv(sshpam_handle, sshpam_conninfo); |
758 |
pam_putenv(*sshpam_phandle, sshpam_conninfo); |
| 729 |
} |
759 |
} |
| 730 |
|
760 |
|
| 731 |
#ifdef PAM_TTY_KLUDGE |
761 |
#ifdef PAM_TTY_KLUDGE |
|
Lines 735-744
sshpam_init(struct ssh *ssh, Authctxt *authctxt)
Link Here
|
| 735 |
* may not even set one (for tty-less connections) |
765 |
* may not even set one (for tty-less connections) |
| 736 |
*/ |
766 |
*/ |
| 737 |
debug("PAM: setting PAM_TTY to \"ssh\""); |
767 |
debug("PAM: setting PAM_TTY to \"ssh\""); |
| 738 |
sshpam_err = pam_set_item(sshpam_handle, PAM_TTY, "ssh"); |
768 |
sshpam_err = pam_set_item(*sshpam_phandle, PAM_TTY, "ssh"); |
| 739 |
if (sshpam_err != PAM_SUCCESS) { |
769 |
if (sshpam_err != PAM_SUCCESS) { |
| 740 |
pam_end(sshpam_handle, sshpam_err); |
770 |
pam_end(*sshpam_phandle, sshpam_err); |
| 741 |
sshpam_handle = NULL; |
771 |
*sshpam_phandle = NULL; |
| 742 |
return (-1); |
772 |
return (-1); |
| 743 |
} |
773 |
} |
| 744 |
#endif |
774 |
#endif |
|
Lines 771-776
sshpam_init_ctx(Authctxt *authctxt)
Link Here
|
| 771 |
{ |
801 |
{ |
| 772 |
struct pam_ctxt *ctxt; |
802 |
struct pam_ctxt *ctxt; |
| 773 |
int socks[2]; |
803 |
int socks[2]; |
|
|
804 |
char *service_name = SSHD_PAM_SERVICE; |
| 774 |
|
805 |
|
| 775 |
debug3("PAM: %s entering", __func__); |
806 |
debug3("PAM: %s entering", __func__); |
| 776 |
/* |
807 |
/* |
|
Lines 780-787
sshpam_init_ctx(Authctxt *authctxt)
Link Here
|
| 780 |
if (!options.use_pam || sshpam_account_status == 0) |
811 |
if (!options.use_pam || sshpam_account_status == 0) |
| 781 |
return NULL; |
812 |
return NULL; |
| 782 |
|
813 |
|
|
|
814 |
if (!( options.pam_service_name == NULL || strcasecmp(options.pam_service_name, "none") == 0)) |
| 815 |
service_name = options.pam_service_name; |
| 816 |
|
| 783 |
/* Initialize PAM */ |
817 |
/* Initialize PAM */ |
| 784 |
if (sshpam_init(NULL, authctxt) == -1) { |
818 |
if (sshpam_init(NULL, authctxt, service_name, &sshpam_handle) == -1) { |
| 785 |
error("PAM: initialization failed"); |
819 |
error("PAM: initialization failed"); |
| 786 |
return (NULL); |
820 |
return (NULL); |
| 787 |
} |
821 |
} |
|
Lines 1022-1032
void
Link Here
|
| 1022 |
start_pam(struct ssh *ssh) |
1056 |
start_pam(struct ssh *ssh) |
| 1023 |
{ |
1057 |
{ |
| 1024 |
Authctxt *authctxt = (Authctxt *)ssh->authctxt; |
1058 |
Authctxt *authctxt = (Authctxt *)ssh->authctxt; |
|
|
1059 |
char *service_name = SSHD_PAM_SERVICE; |
| 1025 |
|
1060 |
|
| 1026 |
if (!options.use_pam) |
1061 |
if (!options.use_pam) |
| 1027 |
fatal("PAM: initialisation requested when UsePAM=no"); |
1062 |
fatal("PAM: initialisation requested when UsePAM=no"); |
| 1028 |
|
1063 |
|
| 1029 |
if (sshpam_init(ssh, authctxt) == -1) |
1064 |
if (!( options.pam_service_name == NULL || strcasecmp(options.pam_service_name, "none") == 0)) |
|
|
1065 |
service_name = options.pam_service_name; |
| 1066 |
|
| 1067 |
if (sshpam_init(ssh, authctxt, service_name, &sshpam_handle) == -1) |
| 1030 |
fatal("PAM: initialisation failed"); |
1068 |
fatal("PAM: initialisation failed"); |
| 1031 |
} |
1069 |
} |
| 1032 |
|
1070 |
|
|
Lines 1316-1325
sshpam_auth_passwd(Authctxt *authctxt, const char *password)
Link Here
|
| 1316 |
int flags = (options.permit_empty_passwd == 0 ? |
1354 |
int flags = (options.permit_empty_passwd == 0 ? |
| 1317 |
PAM_DISALLOW_NULL_AUTHTOK : 0); |
1355 |
PAM_DISALLOW_NULL_AUTHTOK : 0); |
| 1318 |
char *fake = NULL; |
1356 |
char *fake = NULL; |
|
|
1357 |
char *service_name = SSHD_PAM_SERVICE; |
| 1319 |
|
1358 |
|
| 1320 |
if (!options.use_pam || sshpam_handle == NULL) |
1359 |
if (!options.use_pam) |
| 1321 |
fatal("PAM: %s called when PAM disabled or failed to " |
1360 |
fatal("PAM: %s called when PAM disabled.", __func__); |
| 1322 |
"initialise.", __func__); |
1361 |
|
|
|
1362 |
if (!( options.pam_service_name == NULL || strcasecmp(options.pam_service_name, "none") == 0)) |
| 1363 |
service_name = options.pam_service_name; |
| 1364 |
|
| 1365 |
if (!( options.password_pam_service_name == NULL || strcasecmp(options.password_pam_service_name, "none") == 0)) |
| 1366 |
service_name = options.password_pam_service_name; |
| 1367 |
|
| 1368 |
if (sshpam_init(NULL, authctxt, service_name, &sshpam_password_handle) == -1) |
| 1369 |
fatal("PAM: initialisation for password authentication failed"); |
| 1323 |
|
1370 |
|
| 1324 |
sshpam_password = password; |
1371 |
sshpam_password = password; |
| 1325 |
sshpam_authctxt = authctxt; |
1372 |
sshpam_authctxt = authctxt; |
|
Lines 1333-1345
sshpam_auth_passwd(Authctxt *authctxt, const char *password)
Link Here
|
| 1333 |
options.permit_root_login != PERMIT_YES)) |
1380 |
options.permit_root_login != PERMIT_YES)) |
| 1334 |
sshpam_password = fake = fake_password(password); |
1381 |
sshpam_password = fake = fake_password(password); |
| 1335 |
|
1382 |
|
| 1336 |
sshpam_err = pam_set_item(sshpam_handle, PAM_CONV, |
1383 |
sshpam_err = pam_set_item(sshpam_password_handle, PAM_CONV, |
| 1337 |
(const void *)&passwd_conv); |
1384 |
(const void *)&passwd_conv); |
| 1338 |
if (sshpam_err != PAM_SUCCESS) |
1385 |
if (sshpam_err != PAM_SUCCESS) |
| 1339 |
fatal("PAM: %s: failed to set PAM_CONV: %s", __func__, |
1386 |
fatal("PAM: %s: failed to set PAM_CONV: %s", __func__, |
| 1340 |
pam_strerror(sshpam_handle, sshpam_err)); |
1387 |
pam_strerror(sshpam_password_handle, sshpam_err)); |
| 1341 |
|
1388 |
|
| 1342 |
sshpam_err = pam_authenticate(sshpam_handle, flags); |
1389 |
sshpam_err = pam_authenticate(sshpam_password_handle, flags); |
| 1343 |
sshpam_password = NULL; |
1390 |
sshpam_password = NULL; |
| 1344 |
free(fake); |
1391 |
free(fake); |
| 1345 |
if (sshpam_err == PAM_MAXTRIES) |
1392 |
if (sshpam_err == PAM_MAXTRIES) |
|
Lines 1351-1357
sshpam_auth_passwd(Authctxt *authctxt, const char *password)
Link Here
|
| 1351 |
} else { |
1398 |
} else { |
| 1352 |
debug("PAM: password authentication failed for %.100s: %s", |
1399 |
debug("PAM: password authentication failed for %.100s: %s", |
| 1353 |
authctxt->valid ? authctxt->user : "an illegal user", |
1400 |
authctxt->valid ? authctxt->user : "an illegal user", |
| 1354 |
pam_strerror(sshpam_handle, sshpam_err)); |
1401 |
pam_strerror(sshpam_password_handle, sshpam_err)); |
| 1355 |
return 0; |
1402 |
return 0; |
| 1356 |
} |
1403 |
} |
| 1357 |
} |
1404 |
} |