diff options
-rw-r--r-- | ChangeLog | 12 | ||||
-rw-r--r-- | auth-pam.c | 29 | ||||
-rw-r--r-- | auth-pam.h | 4 | ||||
-rw-r--r-- | auth1.c | 2 | ||||
-rw-r--r-- | auth2.c | 6 | ||||
-rw-r--r-- | monitor.c | 8 | ||||
-rw-r--r-- | monitor_wrap.c | 4 | ||||
-rw-r--r-- | monitor_wrap.h | 2 |
8 files changed, 36 insertions, 31 deletions
@@ -1,6 +1,14 @@ | |||
1 | 20040308 | 1 | 20040308 |
2 | - (dtucker) [sshd.c] Back out rev 1.270 as it caused problems on some | 2 | - (dtucker) [sshd.c] Back out rev 1.270 as it caused problems on some |
3 | platforms (eg SCO, HP-UX) with logging in the wrong TZ. | 3 | platforms (eg SCO, HP-UX) with logging in the wrong TZ. ok djm@ |
4 | - (dtucker) [configure.ac sshd.c openbsd-compat/bsd-misc.h | ||
5 | openbsd-compat/setenv.c] Unset KRB5CCNAME on AIX to prevent it from being | ||
6 | inherited by the child. ok djm@ | ||
7 | - (dtucker) [auth-pam.c auth-pam.h auth1.c auth2.c monitor.c monitor_wrap.c | ||
8 | monitor_wrap.h] Bug #808: Ensure force_pwchange is correctly initialized | ||
9 | even if keyboard-interactive is not used by the client. Prevents segfaults | ||
10 | in some cases where the user's password is expired (note this is not | ||
11 | considered a security exposure). ok djm@ | ||
4 | 12 | ||
5 | 20040307 | 13 | 20040307 |
6 | - (tim) [regress/login-timeout.sh] fix building outside of source tree. | 14 | - (tim) [regress/login-timeout.sh] fix building outside of source tree. |
@@ -861,4 +869,4 @@ | |||
861 | - (djm) Trim deprecated options from INSTALL. Mention UsePAM | 869 | - (djm) Trim deprecated options from INSTALL. Mention UsePAM |
862 | - (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu | 870 | - (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu |
863 | 871 | ||
864 | $Id: ChangeLog,v 1.3278 2004/03/08 11:13:12 dtucker Exp $ | 872 | $Id: ChangeLog,v 1.3279 2004/03/08 12:04:06 dtucker Exp $ |
diff --git a/auth-pam.c b/auth-pam.c index ea361f171..6f2264c5d 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.97 2004/03/04 09:03:54 dtucker Exp $"); | 34 | RCSID("$Id: auth-pam.c,v 1.98 2004/03/08 12:04:06 dtucker Exp $"); |
35 | 35 | ||
36 | #ifdef USE_PAM | 36 | #ifdef USE_PAM |
37 | #if defined(HAVE_SECURITY_PAM_APPL_H) | 37 | #if defined(HAVE_SECURITY_PAM_APPL_H) |
@@ -160,7 +160,7 @@ static int sshpam_session_open = 0; | |||
160 | static int sshpam_cred_established = 0; | 160 | static int sshpam_cred_established = 0; |
161 | static int sshpam_account_status = -1; | 161 | static int sshpam_account_status = -1; |
162 | static char **sshpam_env = NULL; | 162 | static char **sshpam_env = NULL; |
163 | static int *force_pwchange; | 163 | static Authctxt *the_authctxt = NULL; |
164 | 164 | ||
165 | /* Some PAM implementations don't implement this */ | 165 | /* Some PAM implementations don't implement this */ |
166 | #ifndef HAVE_PAM_GETENVLIST | 166 | #ifndef HAVE_PAM_GETENVLIST |
@@ -180,7 +180,9 @@ void | |||
180 | pam_password_change_required(int reqd) | 180 | pam_password_change_required(int reqd) |
181 | { | 181 | { |
182 | debug3("%s %d", __func__, reqd); | 182 | debug3("%s %d", __func__, reqd); |
183 | *force_pwchange = reqd; | 183 | if (the_authctxt == NULL) |
184 | fatal("%s: PAM authctxt not initialized", __func__); | ||
185 | the_authctxt->force_pwchange = reqd; | ||
184 | if (reqd) { | 186 | if (reqd) { |
185 | no_port_forwarding_flag |= 2; | 187 | no_port_forwarding_flag |= 2; |
186 | no_agent_forwarding_flag |= 2; | 188 | no_agent_forwarding_flag |= 2; |
@@ -339,6 +341,9 @@ sshpam_thread(void *ctxtp) | |||
339 | sshpam_conv.conv = sshpam_thread_conv; | 341 | sshpam_conv.conv = sshpam_thread_conv; |
340 | sshpam_conv.appdata_ptr = ctxt; | 342 | sshpam_conv.appdata_ptr = ctxt; |
341 | 343 | ||
344 | if (the_authctxt == NULL) | ||
345 | fatal("%s: PAM authctxt not initialized", __func__); | ||
346 | |||
342 | buffer_init(&buffer); | 347 | buffer_init(&buffer); |
343 | sshpam_err = pam_set_item(sshpam_handle, PAM_CONV, | 348 | sshpam_err = pam_set_item(sshpam_handle, PAM_CONV, |
344 | (const void *)&sshpam_conv); | 349 | (const void *)&sshpam_conv); |
@@ -351,7 +356,7 @@ sshpam_thread(void *ctxtp) | |||
351 | if (compat20) { | 356 | if (compat20) { |
352 | if (!do_pam_account()) | 357 | if (!do_pam_account()) |
353 | goto auth_fail; | 358 | goto auth_fail; |
354 | if (*force_pwchange) { | 359 | if (the_authctxt->force_pwchange) { |
355 | sshpam_err = pam_chauthtok(sshpam_handle, | 360 | sshpam_err = pam_chauthtok(sshpam_handle, |
356 | PAM_CHANGE_EXPIRED_AUTHTOK); | 361 | PAM_CHANGE_EXPIRED_AUTHTOK); |
357 | if (sshpam_err != PAM_SUCCESS) | 362 | if (sshpam_err != PAM_SUCCESS) |
@@ -365,7 +370,7 @@ sshpam_thread(void *ctxtp) | |||
365 | #ifndef USE_POSIX_THREADS | 370 | #ifndef USE_POSIX_THREADS |
366 | /* Export variables set by do_pam_account */ | 371 | /* Export variables set by do_pam_account */ |
367 | buffer_put_int(&buffer, sshpam_account_status); | 372 | buffer_put_int(&buffer, sshpam_account_status); |
368 | buffer_put_int(&buffer, *force_pwchange); | 373 | buffer_put_int(&buffer, the_authctxt->force_pwchange); |
369 | 374 | ||
370 | /* Export any environment strings set in child */ | 375 | /* Export any environment strings set in child */ |
371 | for(i = 0; environ[i] != NULL; i++) | 376 | for(i = 0; environ[i] != NULL; i++) |
@@ -446,11 +451,11 @@ sshpam_cleanup(void) | |||
446 | } | 451 | } |
447 | 452 | ||
448 | static int | 453 | static int |
449 | sshpam_init(const char *user) | 454 | sshpam_init(Authctxt *authctxt) |
450 | { | 455 | { |
451 | extern u_int utmp_len; | 456 | extern u_int utmp_len; |
452 | extern char *__progname; | 457 | extern char *__progname; |
453 | const char *pam_rhost, *pam_user; | 458 | const char *pam_rhost, *pam_user, *user = authctxt->user; |
454 | 459 | ||
455 | if (sshpam_handle != NULL) { | 460 | if (sshpam_handle != NULL) { |
456 | /* We already have a PAM context; check if the user matches */ | 461 | /* We already have a PAM context; check if the user matches */ |
@@ -464,6 +469,8 @@ sshpam_init(const char *user) | |||
464 | debug("PAM: initializing for \"%s\"", user); | 469 | debug("PAM: initializing for \"%s\"", user); |
465 | sshpam_err = | 470 | sshpam_err = |
466 | pam_start(SSHD_PAM_SERVICE, user, &null_conv, &sshpam_handle); | 471 | pam_start(SSHD_PAM_SERVICE, user, &null_conv, &sshpam_handle); |
472 | the_authctxt = authctxt; | ||
473 | |||
467 | if (sshpam_err != PAM_SUCCESS) { | 474 | if (sshpam_err != PAM_SUCCESS) { |
468 | pam_end(sshpam_handle, sshpam_err); | 475 | pam_end(sshpam_handle, sshpam_err); |
469 | sshpam_handle = NULL; | 476 | sshpam_handle = NULL; |
@@ -506,7 +513,7 @@ sshpam_init_ctx(Authctxt *authctxt) | |||
506 | return NULL; | 513 | return NULL; |
507 | 514 | ||
508 | /* Initialize PAM */ | 515 | /* Initialize PAM */ |
509 | if (sshpam_init(authctxt->user) == -1) { | 516 | if (sshpam_init(authctxt) == -1) { |
510 | error("PAM: initialization failed"); | 517 | error("PAM: initialization failed"); |
511 | return (NULL); | 518 | return (NULL); |
512 | } | 519 | } |
@@ -514,8 +521,6 @@ sshpam_init_ctx(Authctxt *authctxt) | |||
514 | ctxt = xmalloc(sizeof *ctxt); | 521 | ctxt = xmalloc(sizeof *ctxt); |
515 | memset(ctxt, 0, sizeof(*ctxt)); | 522 | memset(ctxt, 0, sizeof(*ctxt)); |
516 | 523 | ||
517 | force_pwchange = &(authctxt->force_pwchange); | ||
518 | |||
519 | /* Start the authentication thread */ | 524 | /* Start the authentication thread */ |
520 | if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, socks) == -1) { | 525 | if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, socks) == -1) { |
521 | error("PAM: failed create sockets: %s", strerror(errno)); | 526 | error("PAM: failed create sockets: %s", strerror(errno)); |
@@ -674,12 +679,12 @@ KbdintDevice mm_sshpam_device = { | |||
674 | * This replaces auth-pam.c | 679 | * This replaces auth-pam.c |
675 | */ | 680 | */ |
676 | void | 681 | void |
677 | start_pam(const char *user) | 682 | start_pam(Authctxt *authctxt) |
678 | { | 683 | { |
679 | if (!options.use_pam) | 684 | if (!options.use_pam) |
680 | fatal("PAM: initialisation requested when UsePAM=no"); | 685 | fatal("PAM: initialisation requested when UsePAM=no"); |
681 | 686 | ||
682 | if (sshpam_init(user) == -1) | 687 | if (sshpam_init(authctxt) == -1) |
683 | fatal("PAM: initialisation failed"); | 688 | fatal("PAM: initialisation failed"); |
684 | } | 689 | } |
685 | 690 | ||
diff --git a/auth-pam.h b/auth-pam.h index 4bc8d6955..1b3706e07 100644 --- a/auth-pam.h +++ b/auth-pam.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $Id: auth-pam.h,v 1.24 2004/02/10 02:23:29 dtucker Exp $ */ | 1 | /* $Id: auth-pam.h,v 1.25 2004/03/08 12:04:07 dtucker Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Copyright (c) 2000 Damien Miller. All rights reserved. | 4 | * Copyright (c) 2000 Damien Miller. All rights reserved. |
@@ -31,7 +31,7 @@ | |||
31 | # define SSHD_PAM_SERVICE __progname | 31 | # define SSHD_PAM_SERVICE __progname |
32 | #endif | 32 | #endif |
33 | 33 | ||
34 | void start_pam(const char *); | 34 | void start_pam(Authctxt *); |
35 | void finish_pam(void); | 35 | void finish_pam(void); |
36 | u_int do_pam_account(void); | 36 | u_int do_pam_account(void); |
37 | void do_pam_session(void); | 37 | void do_pam_session(void); |
@@ -307,7 +307,7 @@ do_authentication(Authctxt *authctxt) | |||
307 | 307 | ||
308 | #ifdef USE_PAM | 308 | #ifdef USE_PAM |
309 | if (options.use_pam) | 309 | if (options.use_pam) |
310 | PRIVSEP(start_pam(user)); | 310 | PRIVSEP(start_pam(authctxt)); |
311 | #endif | 311 | #endif |
312 | 312 | ||
313 | /* | 313 | /* |
@@ -150,24 +150,24 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt) | |||
150 | if (authctxt->attempt++ == 0) { | 150 | if (authctxt->attempt++ == 0) { |
151 | /* setup auth context */ | 151 | /* setup auth context */ |
152 | authctxt->pw = PRIVSEP(getpwnamallow(user)); | 152 | authctxt->pw = PRIVSEP(getpwnamallow(user)); |
153 | authctxt->user = xstrdup(user); | ||
153 | if (authctxt->pw && strcmp(service, "ssh-connection")==0) { | 154 | if (authctxt->pw && strcmp(service, "ssh-connection")==0) { |
154 | authctxt->valid = 1; | 155 | authctxt->valid = 1; |
155 | debug2("input_userauth_request: setting up authctxt for %s", user); | 156 | debug2("input_userauth_request: setting up authctxt for %s", user); |
156 | #ifdef USE_PAM | 157 | #ifdef USE_PAM |
157 | if (options.use_pam) | 158 | if (options.use_pam) |
158 | PRIVSEP(start_pam(authctxt->pw->pw_name)); | 159 | PRIVSEP(start_pam(authctxt)); |
159 | #endif | 160 | #endif |
160 | } else { | 161 | } else { |
161 | logit("input_userauth_request: illegal user %s", user); | 162 | logit("input_userauth_request: illegal user %s", user); |
162 | authctxt->pw = fakepw(); | 163 | authctxt->pw = fakepw(); |
163 | #ifdef USE_PAM | 164 | #ifdef USE_PAM |
164 | if (options.use_pam) | 165 | if (options.use_pam) |
165 | PRIVSEP(start_pam(user)); | 166 | PRIVSEP(start_pam(authctxt)); |
166 | #endif | 167 | #endif |
167 | } | 168 | } |
168 | setproctitle("%s%s", authctxt->pw ? user : "unknown", | 169 | setproctitle("%s%s", authctxt->pw ? user : "unknown", |
169 | use_privsep ? " [net]" : ""); | 170 | use_privsep ? " [net]" : ""); |
170 | authctxt->user = xstrdup(user); | ||
171 | authctxt->service = xstrdup(service); | 171 | authctxt->service = xstrdup(service); |
172 | authctxt->style = style ? xstrdup(style) : NULL; | 172 | authctxt->style = style ? xstrdup(style) : NULL; |
173 | if (use_privsep) | 173 | if (use_privsep) |
@@ -782,16 +782,10 @@ mm_answer_skeyrespond(int socket, Buffer *m) | |||
782 | int | 782 | int |
783 | mm_answer_pam_start(int socket, Buffer *m) | 783 | mm_answer_pam_start(int socket, Buffer *m) |
784 | { | 784 | { |
785 | char *user; | ||
786 | |||
787 | if (!options.use_pam) | 785 | if (!options.use_pam) |
788 | fatal("UsePAM not set, but ended up in %s anyway", __func__); | 786 | fatal("UsePAM not set, but ended up in %s anyway", __func__); |
789 | 787 | ||
790 | user = buffer_get_string(m, NULL); | 788 | start_pam(authctxt); |
791 | |||
792 | start_pam(user); | ||
793 | |||
794 | xfree(user); | ||
795 | 789 | ||
796 | monitor_permit(mon_dispatch, MONITOR_REQ_PAM_ACCOUNT, 1); | 790 | monitor_permit(mon_dispatch, MONITOR_REQ_PAM_ACCOUNT, 1); |
797 | 791 | ||
diff --git a/monitor_wrap.c b/monitor_wrap.c index e7c15cecd..b1b1c3a61 100644 --- a/monitor_wrap.c +++ b/monitor_wrap.c | |||
@@ -686,7 +686,7 @@ mm_session_pty_cleanup2(Session *s) | |||
686 | 686 | ||
687 | #ifdef USE_PAM | 687 | #ifdef USE_PAM |
688 | void | 688 | void |
689 | mm_start_pam(char *user) | 689 | mm_start_pam(Authctxt *authctxt) |
690 | { | 690 | { |
691 | Buffer m; | 691 | Buffer m; |
692 | 692 | ||
@@ -695,8 +695,6 @@ mm_start_pam(char *user) | |||
695 | fatal("UsePAM=no, but ended up in %s anyway", __func__); | 695 | fatal("UsePAM=no, but ended up in %s anyway", __func__); |
696 | 696 | ||
697 | buffer_init(&m); | 697 | buffer_init(&m); |
698 | buffer_put_cstring(&m, user); | ||
699 | |||
700 | mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_START, &m); | 698 | mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_START, &m); |
701 | 699 | ||
702 | buffer_free(&m); | 700 | buffer_free(&m); |
diff --git a/monitor_wrap.h b/monitor_wrap.h index 55be10b19..2170b1324 100644 --- a/monitor_wrap.h +++ b/monitor_wrap.h | |||
@@ -66,7 +66,7 @@ OM_uint32 mm_ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t); | |||
66 | #endif | 66 | #endif |
67 | 67 | ||
68 | #ifdef USE_PAM | 68 | #ifdef USE_PAM |
69 | void mm_start_pam(char *); | 69 | void mm_start_pam(struct Authctxt *); |
70 | u_int mm_do_pam_account(void); | 70 | u_int mm_do_pam_account(void); |
71 | void *mm_sshpam_init_ctx(struct Authctxt *); | 71 | void *mm_sshpam_init_ctx(struct Authctxt *); |
72 | int mm_sshpam_query(void *, char **, char **, u_int *, char ***, u_int **); | 72 | int mm_sshpam_query(void *, char **, char **, u_int *, char ***, u_int **); |