diff options
Diffstat (limited to 'auth-pam.c')
-rw-r--r-- | auth-pam.c | 45 |
1 files changed, 30 insertions, 15 deletions
diff --git a/auth-pam.c b/auth-pam.c index a8d372aac..0446cd559 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" |
50 | RCSID("$Id: auth-pam.c,v 1.122 2005/05/25 06:18:10 dtucker Exp $"); | 50 | RCSID("$Id: auth-pam.c,v 1.126 2005/07/17 07:18:50 djm 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) |
@@ -56,6 +56,13 @@ RCSID("$Id: auth-pam.c,v 1.122 2005/05/25 06:18:10 dtucker Exp $"); | |||
56 | #include <pam/pam_appl.h> | 56 | #include <pam/pam_appl.h> |
57 | #endif | 57 | #endif |
58 | 58 | ||
59 | /* OpenGroup RFC86.0 and XSSO specify no "const" on arguments */ | ||
60 | #ifdef PAM_SUN_CODEBASE | ||
61 | # define sshpam_const /* Solaris, HP-UX, AIX */ | ||
62 | #else | ||
63 | # define sshpam_const const /* LinuxPAM, OpenPAM */ | ||
64 | #endif | ||
65 | |||
59 | #include "auth.h" | 66 | #include "auth.h" |
60 | #include "auth-pam.h" | 67 | #include "auth-pam.h" |
61 | #include "buffer.h" | 68 | #include "buffer.h" |
@@ -116,14 +123,14 @@ static struct pam_ctxt *cleanup_ctxt; | |||
116 | static int sshpam_thread_status = -1; | 123 | static int sshpam_thread_status = -1; |
117 | static mysig_t sshpam_oldsig; | 124 | static mysig_t sshpam_oldsig; |
118 | 125 | ||
119 | static void | 126 | static void |
120 | sshpam_sigchld_handler(int sig) | 127 | sshpam_sigchld_handler(int sig) |
121 | { | 128 | { |
122 | signal(SIGCHLD, SIG_DFL); | 129 | signal(SIGCHLD, SIG_DFL); |
123 | if (cleanup_ctxt == NULL) | 130 | if (cleanup_ctxt == NULL) |
124 | return; /* handler called after PAM cleanup, shouldn't happen */ | 131 | return; /* handler called after PAM cleanup, shouldn't happen */ |
125 | if (waitpid(cleanup_ctxt->pam_thread, &sshpam_thread_status, WNOHANG) | 132 | if (waitpid(cleanup_ctxt->pam_thread, &sshpam_thread_status, WNOHANG) |
126 | <= 0) { | 133 | <= 0) { |
127 | /* PAM thread has not exitted, privsep slave must have */ | 134 | /* PAM thread has not exitted, privsep slave must have */ |
128 | kill(cleanup_ctxt->pam_thread, SIGTERM); | 135 | kill(cleanup_ctxt->pam_thread, SIGTERM); |
129 | if (waitpid(cleanup_ctxt->pam_thread, &sshpam_thread_status, 0) | 136 | if (waitpid(cleanup_ctxt->pam_thread, &sshpam_thread_status, 0) |
@@ -150,6 +157,7 @@ pthread_create(sp_pthread_t *thread, const void *attr __unused, | |||
150 | void *(*thread_start)(void *), void *arg) | 157 | void *(*thread_start)(void *), void *arg) |
151 | { | 158 | { |
152 | pid_t pid; | 159 | pid_t pid; |
160 | struct pam_ctxt *ctx = arg; | ||
153 | 161 | ||
154 | sshpam_thread_status = -1; | 162 | sshpam_thread_status = -1; |
155 | switch ((pid = fork())) { | 163 | switch ((pid = fork())) { |
@@ -157,10 +165,14 @@ pthread_create(sp_pthread_t *thread, const void *attr __unused, | |||
157 | error("fork(): %s", strerror(errno)); | 165 | error("fork(): %s", strerror(errno)); |
158 | return (-1); | 166 | return (-1); |
159 | case 0: | 167 | case 0: |
168 | close(ctx->pam_psock); | ||
169 | ctx->pam_psock = -1; | ||
160 | thread_start(arg); | 170 | thread_start(arg); |
161 | _exit(1); | 171 | _exit(1); |
162 | default: | 172 | default: |
163 | *thread = pid; | 173 | *thread = pid; |
174 | close(ctx->pam_csock); | ||
175 | ctx->pam_csock = -1; | ||
164 | sshpam_oldsig = signal(SIGCHLD, sshpam_sigchld_handler); | 176 | sshpam_oldsig = signal(SIGCHLD, sshpam_sigchld_handler); |
165 | return (0); | 177 | return (0); |
166 | } | 178 | } |
@@ -300,7 +312,7 @@ import_environments(Buffer *b) | |||
300 | * Conversation function for authentication thread. | 312 | * Conversation function for authentication thread. |
301 | */ | 313 | */ |
302 | static int | 314 | static int |
303 | sshpam_thread_conv(int n, struct pam_message **msg, | 315 | sshpam_thread_conv(int n, sshpam_const struct pam_message **msg, |
304 | struct pam_response **resp, void *data) | 316 | struct pam_response **resp, void *data) |
305 | { | 317 | { |
306 | Buffer buffer; | 318 | Buffer buffer; |
@@ -399,8 +411,10 @@ sshpam_thread(void *ctxtp) | |||
399 | char **env_from_pam; | 411 | char **env_from_pam; |
400 | u_int i; | 412 | u_int i; |
401 | const char *pam_user; | 413 | const char *pam_user; |
414 | const char **ptr_pam_user = &pam_user; | ||
402 | 415 | ||
403 | pam_get_item(sshpam_handle, PAM_USER, (void **)&pam_user); | 416 | pam_get_item(sshpam_handle, PAM_USER, |
417 | (sshpam_const void **)ptr_pam_user); | ||
404 | environ[0] = NULL; | 418 | environ[0] = NULL; |
405 | 419 | ||
406 | if (sshpam_authctxt != NULL) { | 420 | if (sshpam_authctxt != NULL) { |
@@ -492,7 +506,7 @@ sshpam_thread_cleanup(void) | |||
492 | } | 506 | } |
493 | 507 | ||
494 | static int | 508 | static int |
495 | sshpam_null_conv(int n, struct pam_message **msg, | 509 | sshpam_null_conv(int n, sshpam_const struct pam_message **msg, |
496 | struct pam_response **resp, void *data) | 510 | struct pam_response **resp, void *data) |
497 | { | 511 | { |
498 | debug3("PAM: %s entering, %d messages", __func__, n); | 512 | debug3("PAM: %s entering, %d messages", __func__, n); |
@@ -502,7 +516,7 @@ sshpam_null_conv(int n, struct pam_message **msg, | |||
502 | static struct pam_conv null_conv = { sshpam_null_conv, NULL }; | 516 | static struct pam_conv null_conv = { sshpam_null_conv, NULL }; |
503 | 517 | ||
504 | static int | 518 | static int |
505 | sshpam_store_conv(int n, struct pam_message **msg, | 519 | sshpam_store_conv(int n, sshpam_const struct pam_message **msg, |
506 | struct pam_response **resp, void *data) | 520 | struct pam_response **resp, void *data) |
507 | { | 521 | { |
508 | struct pam_response *reply; | 522 | struct pam_response *reply; |
@@ -571,11 +585,12 @@ sshpam_init(Authctxt *authctxt) | |||
571 | { | 585 | { |
572 | extern char *__progname; | 586 | extern char *__progname; |
573 | const char *pam_rhost, *pam_user, *user = authctxt->user; | 587 | const char *pam_rhost, *pam_user, *user = authctxt->user; |
588 | const char **ptr_pam_user = &pam_user; | ||
574 | 589 | ||
575 | if (sshpam_handle != NULL) { | 590 | if (sshpam_handle != NULL) { |
576 | /* We already have a PAM context; check if the user matches */ | 591 | /* We already have a PAM context; check if the user matches */ |
577 | sshpam_err = pam_get_item(sshpam_handle, | 592 | sshpam_err = pam_get_item(sshpam_handle, |
578 | PAM_USER, (void **)&pam_user); | 593 | PAM_USER, (sshpam_const void **)ptr_pam_user); |
579 | if (sshpam_err == PAM_SUCCESS && strcmp(user, pam_user) == 0) | 594 | if (sshpam_err == PAM_SUCCESS && strcmp(user, pam_user) == 0) |
580 | return (0); | 595 | return (0); |
581 | pam_end(sshpam_handle, sshpam_err); | 596 | pam_end(sshpam_handle, sshpam_err); |
@@ -765,7 +780,7 @@ sshpam_respond(void *ctx, u_int num, char **resp) | |||
765 | buffer_init(&buffer); | 780 | buffer_init(&buffer); |
766 | if (sshpam_authctxt->valid && | 781 | if (sshpam_authctxt->valid && |
767 | (sshpam_authctxt->pw->pw_uid != 0 || | 782 | (sshpam_authctxt->pw->pw_uid != 0 || |
768 | options.permit_root_login == PERMIT_YES)) | 783 | options.permit_root_login == PERMIT_YES)) |
769 | buffer_put_cstring(&buffer, *resp); | 784 | buffer_put_cstring(&buffer, *resp); |
770 | else | 785 | else |
771 | buffer_put_cstring(&buffer, badpw); | 786 | buffer_put_cstring(&buffer, badpw); |
@@ -838,7 +853,7 @@ do_pam_account(void) | |||
838 | sshpam_err = pam_acct_mgmt(sshpam_handle, 0); | 853 | sshpam_err = pam_acct_mgmt(sshpam_handle, 0); |
839 | debug3("PAM: %s pam_acct_mgmt = %d (%s)", __func__, sshpam_err, | 854 | debug3("PAM: %s pam_acct_mgmt = %d (%s)", __func__, sshpam_err, |
840 | pam_strerror(sshpam_handle, sshpam_err)); | 855 | pam_strerror(sshpam_handle, sshpam_err)); |
841 | 856 | ||
842 | if (sshpam_err != PAM_SUCCESS && sshpam_err != PAM_NEW_AUTHTOK_REQD) { | 857 | if (sshpam_err != PAM_SUCCESS && sshpam_err != PAM_NEW_AUTHTOK_REQD) { |
843 | sshpam_account_status = 0; | 858 | sshpam_account_status = 0; |
844 | return (sshpam_account_status); | 859 | return (sshpam_account_status); |
@@ -891,7 +906,7 @@ do_pam_setcred(int init) | |||
891 | } | 906 | } |
892 | 907 | ||
893 | static int | 908 | static int |
894 | sshpam_tty_conv(int n, struct pam_message **msg, | 909 | sshpam_tty_conv(int n, sshpam_const struct pam_message **msg, |
895 | struct pam_response **resp, void *data) | 910 | struct pam_response **resp, void *data) |
896 | { | 911 | { |
897 | char input[PAM_MAX_MSG_SIZE]; | 912 | char input[PAM_MAX_MSG_SIZE]; |
@@ -1050,7 +1065,7 @@ free_pam_environment(char **env) | |||
1050 | * display. | 1065 | * display. |
1051 | */ | 1066 | */ |
1052 | static int | 1067 | static int |
1053 | sshpam_passwd_conv(int n, struct pam_message **msg, | 1068 | sshpam_passwd_conv(int n, sshpam_const struct pam_message **msg, |
1054 | struct pam_response **resp, void *data) | 1069 | struct pam_response **resp, void *data) |
1055 | { | 1070 | { |
1056 | struct pam_response *reply; | 1071 | struct pam_response *reply; |
@@ -1096,7 +1111,7 @@ sshpam_passwd_conv(int n, struct pam_message **msg, | |||
1096 | *resp = reply; | 1111 | *resp = reply; |
1097 | return (PAM_SUCCESS); | 1112 | return (PAM_SUCCESS); |
1098 | 1113 | ||
1099 | fail: | 1114 | fail: |
1100 | for(i = 0; i < n; i++) { | 1115 | for(i = 0; i < n; i++) { |
1101 | if (reply[i].resp != NULL) | 1116 | if (reply[i].resp != NULL) |
1102 | xfree(reply[i].resp); | 1117 | xfree(reply[i].resp); |
@@ -1129,7 +1144,7 @@ sshpam_auth_passwd(Authctxt *authctxt, const char *password) | |||
1129 | * information via timing (eg if the PAM config has a delay on fail). | 1144 | * information via timing (eg if the PAM config has a delay on fail). |
1130 | */ | 1145 | */ |
1131 | if (!authctxt->valid || (authctxt->pw->pw_uid == 0 && | 1146 | if (!authctxt->valid || (authctxt->pw->pw_uid == 0 && |
1132 | options.permit_root_login != PERMIT_YES)) | 1147 | options.permit_root_login != PERMIT_YES)) |
1133 | sshpam_password = badpw; | 1148 | sshpam_password = badpw; |
1134 | 1149 | ||
1135 | sshpam_err = pam_set_item(sshpam_handle, PAM_CONV, | 1150 | sshpam_err = pam_set_item(sshpam_handle, PAM_CONV, |
@@ -1143,7 +1158,7 @@ sshpam_auth_passwd(Authctxt *authctxt, const char *password) | |||
1143 | if (sshpam_err == PAM_SUCCESS && authctxt->valid) { | 1158 | if (sshpam_err == PAM_SUCCESS && authctxt->valid) { |
1144 | debug("PAM: password authentication accepted for %.100s", | 1159 | debug("PAM: password authentication accepted for %.100s", |
1145 | authctxt->user); | 1160 | authctxt->user); |
1146 | return 1; | 1161 | return 1; |
1147 | } else { | 1162 | } else { |
1148 | debug("PAM: password authentication failed for %.100s: %s", | 1163 | debug("PAM: password authentication failed for %.100s: %s", |
1149 | authctxt->valid ? authctxt->user : "an illegal user", | 1164 | authctxt->valid ? authctxt->user : "an illegal user", |