summaryrefslogtreecommitdiff
path: root/auth-pam.c
diff options
context:
space:
mode:
authorDarren Tucker <dtucker@zip.com.au>2003-12-18 15:34:31 +1100
committerDarren Tucker <dtucker@zip.com.au>2003-12-18 15:34:31 +1100
commit07705c788e9bcd8d35dfbb59d2b12c61b8601c9a (patch)
treed4807d0bcb5fd73825cf4d03c89213fab34a9bd7 /auth-pam.c
parent454da0b3dcf8b62b57ff5cf1edfa606b90f553d2 (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.
Diffstat (limited to 'auth-pam.c')
-rw-r--r--auth-pam.c64
1 files changed, 51 insertions, 13 deletions
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"
34RCSID("$Id: auth-pam.c,v 1.84 2003/11/21 12:56:47 djm Exp $"); 34RCSID("$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
54extern ServerOptions options; 54extern ServerOptions options;
55extern Buffer loginmsg; 55extern Buffer loginmsg;
56extern int compat20;
56 57
57#define __unused 58#define __unused
58 59
@@ -118,6 +119,7 @@ static int sshpam_authenticated = 0;
118static int sshpam_new_authtok_reqd = 0; 119static int sshpam_new_authtok_reqd = 0;
119static int sshpam_session_open = 0; 120static int sshpam_session_open = 0;
120static int sshpam_cred_established = 0; 121static int sshpam_cred_established = 0;
122static int sshpam_account_status = -1;
121static char **sshpam_env = NULL; 123static char **sshpam_env = NULL;
122 124
123struct pam_ctxt { 125struct pam_ctxt {
@@ -144,6 +146,21 @@ pam_getenvlist(pam_handle_t *pamh)
144} 146}
145#endif 147#endif
146 148
149void
150pam_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 */
148static void 165static void
149import_environments(Buffer *b) 166import_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)
611u_int 649u_int
612do_pam_account(void) 650do_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
632void 670void