diff options
author | Darren Tucker <dtucker@zip.com.au> | 2003-12-18 15:34:31 +1100 |
---|---|---|
committer | Darren Tucker <dtucker@zip.com.au> | 2003-12-18 15:34:31 +1100 |
commit | 07705c788e9bcd8d35dfbb59d2b12c61b8601c9a (patch) | |
tree | d4807d0bcb5fd73825cf4d03c89213fab34a9bd7 | |
parent | 454da0b3dcf8b62b57ff5cf1edfa606b90f553d2 (diff) |
- (dtucker) [auth-pam.c] Do PAM chauthtok during SSH2 keyboard-interactive
authentication. Partially fixes bug #423. Feedback & ok djm@
Some background on why this is the way it is:
* Solaris 8's pam_chauthtok ignores the CHANGE_EXPIRED_AUTHTOK flag, so
we must call do_pam_account() to figure out if the password is expired.
* AIX 5.2 does not like having pam_acct_mgmt() called twice, once from the
authentication thread and once from the main shell child, so we cache the
result, which must be passed from the authentication thread back to the
monitor.
-rw-r--r-- | ChangeLog | 4 | ||||
-rw-r--r-- | auth-pam.c | 64 |
2 files changed, 54 insertions, 14 deletions
@@ -1,5 +1,7 @@ | |||
1 | 20031218 | 1 | 20031218 |
2 | - (dtucker) [configure.ac] Don't use setre[ug]id on DG-UX, from Tom Orban. | 2 | - (dtucker) [configure.ac] Don't use setre[ug]id on DG-UX, from Tom Orban. |
3 | - (dtucker) [auth-pam.c] Do PAM chauthtok during SSH2 keyboard-interactive | ||
4 | authentication. Partially fixes bug #423. Feedback & ok djm@ | ||
3 | 5 | ||
4 | 20031217 | 6 | 20031217 |
5 | - (djm) OpenBSD CVS Sync | 7 | - (djm) OpenBSD CVS Sync |
@@ -1610,4 +1612,4 @@ | |||
1610 | - Fix sshd BindAddress and -b options for systems using fake-getaddrinfo. | 1612 | - Fix sshd BindAddress and -b options for systems using fake-getaddrinfo. |
1611 | Report from murple@murple.net, diagnosis from dtucker@zip.com.au | 1613 | Report from murple@murple.net, diagnosis from dtucker@zip.com.au |
1612 | 1614 | ||
1613 | $Id: ChangeLog,v 1.3150 2003/12/18 01:52:19 dtucker Exp $ | 1615 | $Id: ChangeLog,v 1.3151 2003/12/18 04:34:31 dtucker Exp $ |
diff --git a/auth-pam.c b/auth-pam.c index 621940ab9..2fe1e3382 100644 --- a/auth-pam.c +++ b/auth-pam.c | |||
@@ -31,7 +31,7 @@ | |||
31 | 31 | ||
32 | /* Based on $FreeBSD: src/crypto/openssh/auth2-pam-freebsd.c,v 1.11 2003/03/31 13:48:18 des Exp $ */ | 32 | /* Based on $FreeBSD: src/crypto/openssh/auth2-pam-freebsd.c,v 1.11 2003/03/31 13:48:18 des Exp $ */ |
33 | #include "includes.h" | 33 | #include "includes.h" |
34 | RCSID("$Id: auth-pam.c,v 1.84 2003/11/21 12:56:47 djm Exp $"); | 34 | RCSID("$Id: auth-pam.c,v 1.85 2003/12/18 04:34:32 dtucker Exp $"); |
35 | 35 | ||
36 | #ifdef USE_PAM | 36 | #ifdef USE_PAM |
37 | #include <security/pam_appl.h> | 37 | #include <security/pam_appl.h> |
@@ -53,6 +53,7 @@ RCSID("$Id: auth-pam.c,v 1.84 2003/11/21 12:56:47 djm Exp $"); | |||
53 | 53 | ||
54 | extern ServerOptions options; | 54 | extern ServerOptions options; |
55 | extern Buffer loginmsg; | 55 | extern Buffer loginmsg; |
56 | extern int compat20; | ||
56 | 57 | ||
57 | #define __unused | 58 | #define __unused |
58 | 59 | ||
@@ -118,6 +119,7 @@ static int sshpam_authenticated = 0; | |||
118 | static int sshpam_new_authtok_reqd = 0; | 119 | static int sshpam_new_authtok_reqd = 0; |
119 | static int sshpam_session_open = 0; | 120 | static int sshpam_session_open = 0; |
120 | static int sshpam_cred_established = 0; | 121 | static int sshpam_cred_established = 0; |
122 | static int sshpam_account_status = -1; | ||
121 | static char **sshpam_env = NULL; | 123 | static char **sshpam_env = NULL; |
122 | 124 | ||
123 | struct pam_ctxt { | 125 | struct pam_ctxt { |
@@ -144,6 +146,21 @@ pam_getenvlist(pam_handle_t *pamh) | |||
144 | } | 146 | } |
145 | #endif | 147 | #endif |
146 | 148 | ||
149 | void | ||
150 | pam_password_change_required(int reqd) | ||
151 | { | ||
152 | sshpam_new_authtok_reqd = reqd; | ||
153 | if (reqd) { | ||
154 | no_port_forwarding_flag |= 2; | ||
155 | no_agent_forwarding_flag |= 2; | ||
156 | no_x11_forwarding_flag |= 2; | ||
157 | } else { | ||
158 | no_port_forwarding_flag &= ~2; | ||
159 | no_agent_forwarding_flag &= ~2; | ||
160 | no_x11_forwarding_flag &= ~2; | ||
161 | |||
162 | } | ||
163 | } | ||
147 | /* Import regular and PAM environment from subprocess */ | 164 | /* Import regular and PAM environment from subprocess */ |
148 | static void | 165 | static void |
149 | import_environments(Buffer *b) | 166 | import_environments(Buffer *b) |
@@ -152,6 +169,10 @@ import_environments(Buffer *b) | |||
152 | u_int i, num_env; | 169 | u_int i, num_env; |
153 | int err; | 170 | int err; |
154 | 171 | ||
172 | /* Import variables set by do_pam_account */ | ||
173 | sshpam_account_status = buffer_get_int(b); | ||
174 | pam_password_change_required(buffer_get_int(b)); | ||
175 | |||
155 | /* Import environment from subprocess */ | 176 | /* Import environment from subprocess */ |
156 | num_env = buffer_get_int(b); | 177 | num_env = buffer_get_int(b); |
157 | sshpam_env = xmalloc((num_env + 1) * sizeof(*sshpam_env)); | 178 | sshpam_env = xmalloc((num_env + 1) * sizeof(*sshpam_env)); |
@@ -290,9 +311,26 @@ sshpam_thread(void *ctxtp) | |||
290 | sshpam_err = pam_authenticate(sshpam_handle, 0); | 311 | sshpam_err = pam_authenticate(sshpam_handle, 0); |
291 | if (sshpam_err != PAM_SUCCESS) | 312 | if (sshpam_err != PAM_SUCCESS) |
292 | goto auth_fail; | 313 | goto auth_fail; |
314 | |||
315 | /* if (compat20) { */ | ||
316 | if (!do_pam_account()) | ||
317 | goto auth_fail; | ||
318 | if (sshpam_new_authtok_reqd) { | ||
319 | sshpam_err = pam_chauthtok(sshpam_handle, | ||
320 | PAM_CHANGE_EXPIRED_AUTHTOK); | ||
321 | if (sshpam_err != PAM_SUCCESS) | ||
322 | goto auth_fail; | ||
323 | pam_password_change_required(0); | ||
324 | } | ||
325 | /* } */ | ||
326 | |||
293 | buffer_put_cstring(&buffer, "OK"); | 327 | buffer_put_cstring(&buffer, "OK"); |
294 | 328 | ||
295 | #ifndef USE_POSIX_THREADS | 329 | #ifndef USE_POSIX_THREADS |
330 | /* Export variables set by do_pam_account */ | ||
331 | buffer_put_int(&buffer, sshpam_account_status); | ||
332 | buffer_put_int(&buffer, sshpam_new_authtok_reqd); | ||
333 | |||
296 | /* Export any environment strings set in child */ | 334 | /* Export any environment strings set in child */ |
297 | for(i = 0; environ[i] != NULL; i++) | 335 | for(i = 0; environ[i] != NULL; i++) |
298 | ; /* Count */ | 336 | ; /* Count */ |
@@ -611,22 +649,22 @@ finish_pam(void) | |||
611 | u_int | 649 | u_int |
612 | do_pam_account(void) | 650 | do_pam_account(void) |
613 | { | 651 | { |
652 | if (sshpam_account_status != -1) | ||
653 | return (sshpam_account_status); | ||
654 | |||
614 | sshpam_err = pam_acct_mgmt(sshpam_handle, 0); | 655 | sshpam_err = pam_acct_mgmt(sshpam_handle, 0); |
615 | debug3("%s: pam_acct_mgmt = %d", __func__, sshpam_err); | 656 | debug3("%s: pam_acct_mgmt = %d", __func__, sshpam_err); |
616 | 657 | ||
617 | if (sshpam_err != PAM_SUCCESS && sshpam_err != PAM_NEW_AUTHTOK_REQD) | 658 | if (sshpam_err != PAM_SUCCESS && sshpam_err != PAM_NEW_AUTHTOK_REQD) { |
618 | return (0); | 659 | sshpam_account_status = 0; |
619 | 660 | return (sshpam_account_status); | |
620 | if (sshpam_err == PAM_NEW_AUTHTOK_REQD) { | ||
621 | sshpam_new_authtok_reqd = 1; | ||
622 | |||
623 | /* Prevent forwardings until password changed */ | ||
624 | no_port_forwarding_flag |= 2; | ||
625 | no_agent_forwarding_flag |= 2; | ||
626 | no_x11_forwarding_flag |= 2; | ||
627 | } | 661 | } |
628 | 662 | ||
629 | return (1); | 663 | if (sshpam_err == PAM_NEW_AUTHTOK_REQD) |
664 | pam_password_change_required(1); | ||
665 | |||
666 | sshpam_account_status = 1; | ||
667 | return (sshpam_account_status); | ||
630 | } | 668 | } |
631 | 669 | ||
632 | void | 670 | void |