diff options
author | Colin Watson <cjwatson@debian.org> | 2009-12-29 21:38:40 +0000 |
---|---|---|
committer | Colin Watson <cjwatson@debian.org> | 2009-12-29 21:38:40 +0000 |
commit | 1b816ea846aca3ee89e7995373ace609e9518424 (patch) | |
tree | b41cdc8495cae7fa9c2e0f98a5f2e71656b61f9a /auth-pam.c | |
parent | fa585019a79ebcb4e0202b1c33f87ff1c5c9ce1c (diff) | |
parent | 086ea76990b1e6287c24b6db74adffd4605eb3b0 (diff) |
import openssh-4.6p1-gsskex-20070312.patch
Diffstat (limited to 'auth-pam.c')
-rw-r--r-- | auth-pam.c | 85 |
1 files changed, 63 insertions, 22 deletions
diff --git a/auth-pam.c b/auth-pam.c index fb9ae954a..c08d47229 100644 --- a/auth-pam.c +++ b/auth-pam.c | |||
@@ -47,7 +47,16 @@ | |||
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.128 2006/01/29 05:46:13 dtucker Exp $"); | 50 | |
51 | #include <sys/types.h> | ||
52 | #include <sys/stat.h> | ||
53 | #include <sys/wait.h> | ||
54 | |||
55 | #include <errno.h> | ||
56 | #include <signal.h> | ||
57 | #include <stdarg.h> | ||
58 | #include <string.h> | ||
59 | #include <unistd.h> | ||
51 | 60 | ||
52 | #ifdef USE_PAM | 61 | #ifdef USE_PAM |
53 | #if defined(HAVE_SECURITY_PAM_APPL_H) | 62 | #if defined(HAVE_SECURITY_PAM_APPL_H) |
@@ -63,20 +72,31 @@ RCSID("$Id: auth-pam.c,v 1.128 2006/01/29 05:46:13 dtucker Exp $"); | |||
63 | # define sshpam_const const /* LinuxPAM, OpenPAM */ | 72 | # define sshpam_const const /* LinuxPAM, OpenPAM */ |
64 | #endif | 73 | #endif |
65 | 74 | ||
75 | /* Ambiguity in spec: is it an array of pointers or a pointer to an array? */ | ||
76 | #ifdef PAM_SUN_CODEBASE | ||
77 | # define PAM_MSG_MEMBER(msg, n, member) ((*(msg))[(n)].member) | ||
78 | #else | ||
79 | # define PAM_MSG_MEMBER(msg, n, member) ((msg)[(n)]->member) | ||
80 | #endif | ||
81 | |||
82 | #include "xmalloc.h" | ||
83 | #include "buffer.h" | ||
84 | #include "key.h" | ||
85 | #include "hostfile.h" | ||
66 | #include "auth.h" | 86 | #include "auth.h" |
67 | #include "auth-pam.h" | 87 | #include "auth-pam.h" |
68 | #include "buffer.h" | ||
69 | #include "bufaux.h" | ||
70 | #include "canohost.h" | 88 | #include "canohost.h" |
71 | #include "log.h" | 89 | #include "log.h" |
72 | #include "monitor_wrap.h" | ||
73 | #include "msg.h" | 90 | #include "msg.h" |
74 | #include "packet.h" | 91 | #include "packet.h" |
75 | #include "misc.h" | 92 | #include "misc.h" |
76 | #include "servconf.h" | 93 | #include "servconf.h" |
77 | #include "ssh2.h" | 94 | #include "ssh2.h" |
78 | #include "xmalloc.h" | ||
79 | #include "auth-options.h" | 95 | #include "auth-options.h" |
96 | #ifdef GSSAPI | ||
97 | #include "ssh-gss.h" | ||
98 | #endif | ||
99 | #include "monitor_wrap.h" | ||
80 | 100 | ||
81 | extern ServerOptions options; | 101 | extern ServerOptions options; |
82 | extern Buffer loginmsg; | 102 | extern Buffer loginmsg; |
@@ -146,14 +166,16 @@ sshpam_sigchld_handler(int sig) | |||
146 | fatal("PAM: authentication thread exited uncleanly"); | 166 | fatal("PAM: authentication thread exited uncleanly"); |
147 | } | 167 | } |
148 | 168 | ||
169 | /* ARGSUSED */ | ||
149 | static void | 170 | static void |
150 | pthread_exit(void *value __unused) | 171 | pthread_exit(void *value) |
151 | { | 172 | { |
152 | _exit(0); | 173 | _exit(0); |
153 | } | 174 | } |
154 | 175 | ||
176 | /* ARGSUSED */ | ||
155 | static int | 177 | static int |
156 | pthread_create(sp_pthread_t *thread, const void *attr __unused, | 178 | pthread_create(sp_pthread_t *thread, const void *attr, |
157 | void *(*thread_start)(void *), void *arg) | 179 | void *(*thread_start)(void *), void *arg) |
158 | { | 180 | { |
159 | pid_t pid; | 181 | pid_t pid; |
@@ -185,8 +207,9 @@ pthread_cancel(sp_pthread_t thread) | |||
185 | return (kill(thread, SIGTERM)); | 207 | return (kill(thread, SIGTERM)); |
186 | } | 208 | } |
187 | 209 | ||
210 | /* ARGSUSED */ | ||
188 | static int | 211 | static int |
189 | pthread_join(sp_pthread_t thread, void **value __unused) | 212 | pthread_join(sp_pthread_t thread, void **value) |
190 | { | 213 | { |
191 | int status; | 214 | int status; |
192 | 215 | ||
@@ -284,7 +307,10 @@ import_environments(Buffer *b) | |||
284 | 307 | ||
285 | /* Import environment from subprocess */ | 308 | /* Import environment from subprocess */ |
286 | num_env = buffer_get_int(b); | 309 | num_env = buffer_get_int(b); |
287 | sshpam_env = xmalloc((num_env + 1) * sizeof(*sshpam_env)); | 310 | if (num_env > 1024) |
311 | fatal("%s: received %u environment variables, expected <= 1024", | ||
312 | __func__, num_env); | ||
313 | sshpam_env = xcalloc(num_env + 1, sizeof(*sshpam_env)); | ||
288 | debug3("PAM: num env strings %d", num_env); | 314 | debug3("PAM: num env strings %d", num_env); |
289 | for(i = 0; i < num_env; i++) | 315 | for(i = 0; i < num_env; i++) |
290 | sshpam_env[i] = buffer_get_string(b, NULL); | 316 | sshpam_env[i] = buffer_get_string(b, NULL); |
@@ -331,9 +357,8 @@ sshpam_thread_conv(int n, sshpam_const struct pam_message **msg, | |||
331 | if (n <= 0 || n > PAM_MAX_NUM_MSG) | 357 | if (n <= 0 || n > PAM_MAX_NUM_MSG) |
332 | return (PAM_CONV_ERR); | 358 | return (PAM_CONV_ERR); |
333 | 359 | ||
334 | if ((reply = malloc(n * sizeof(*reply))) == NULL) | 360 | if ((reply = calloc(n, sizeof(*reply))) == NULL) |
335 | return (PAM_CONV_ERR); | 361 | return (PAM_CONV_ERR); |
336 | memset(reply, 0, n * sizeof(*reply)); | ||
337 | 362 | ||
338 | buffer_init(&buffer); | 363 | buffer_init(&buffer); |
339 | for (i = 0; i < n; ++i) { | 364 | for (i = 0; i < n; ++i) { |
@@ -412,10 +437,16 @@ sshpam_thread(void *ctxtp) | |||
412 | u_int i; | 437 | u_int i; |
413 | const char *pam_user; | 438 | const char *pam_user; |
414 | const char **ptr_pam_user = &pam_user; | 439 | const char **ptr_pam_user = &pam_user; |
440 | char *tz = getenv("TZ"); | ||
415 | 441 | ||
416 | pam_get_item(sshpam_handle, PAM_USER, | 442 | pam_get_item(sshpam_handle, PAM_USER, |
417 | (sshpam_const void **)ptr_pam_user); | 443 | (sshpam_const void **)ptr_pam_user); |
444 | |||
418 | environ[0] = NULL; | 445 | environ[0] = NULL; |
446 | if (tz != NULL) | ||
447 | if (setenv("TZ", tz, 1) == -1) | ||
448 | error("PAM: could not set TZ environment: %s", | ||
449 | strerror(errno)); | ||
419 | 450 | ||
420 | if (sshpam_authctxt != NULL) { | 451 | if (sshpam_authctxt != NULL) { |
421 | setproctitle("%s [pam]", | 452 | setproctitle("%s [pam]", |
@@ -439,8 +470,10 @@ sshpam_thread(void *ctxtp) | |||
439 | goto auth_fail; | 470 | goto auth_fail; |
440 | 471 | ||
441 | if (compat20) { | 472 | if (compat20) { |
442 | if (!do_pam_account()) | 473 | if (!do_pam_account()) { |
474 | sshpam_err = PAM_ACCT_EXPIRED; | ||
443 | goto auth_fail; | 475 | goto auth_fail; |
476 | } | ||
444 | if (sshpam_authctxt->force_pwchange) { | 477 | if (sshpam_authctxt->force_pwchange) { |
445 | sshpam_err = pam_chauthtok(sshpam_handle, | 478 | sshpam_err = pam_chauthtok(sshpam_handle, |
446 | PAM_CHANGE_EXPIRED_AUTHTOK); | 479 | PAM_CHANGE_EXPIRED_AUTHTOK); |
@@ -482,7 +515,10 @@ sshpam_thread(void *ctxtp) | |||
482 | buffer_put_cstring(&buffer, | 515 | buffer_put_cstring(&buffer, |
483 | pam_strerror(sshpam_handle, sshpam_err)); | 516 | pam_strerror(sshpam_handle, sshpam_err)); |
484 | /* XXX - can't do much about an error here */ | 517 | /* XXX - can't do much about an error here */ |
485 | ssh_msg_send(ctxt->pam_csock, PAM_AUTH_ERR, &buffer); | 518 | if (sshpam_err == PAM_ACCT_EXPIRED) |
519 | ssh_msg_send(ctxt->pam_csock, PAM_ACCT_EXPIRED, &buffer); | ||
520 | else | ||
521 | ssh_msg_send(ctxt->pam_csock, PAM_AUTH_ERR, &buffer); | ||
486 | buffer_free(&buffer); | 522 | buffer_free(&buffer); |
487 | pthread_exit(NULL); | 523 | pthread_exit(NULL); |
488 | 524 | ||
@@ -529,9 +565,8 @@ sshpam_store_conv(int n, sshpam_const struct pam_message **msg, | |||
529 | if (n <= 0 || n > PAM_MAX_NUM_MSG) | 565 | if (n <= 0 || n > PAM_MAX_NUM_MSG) |
530 | return (PAM_CONV_ERR); | 566 | return (PAM_CONV_ERR); |
531 | 567 | ||
532 | if ((reply = malloc(n * sizeof(*reply))) == NULL) | 568 | if ((reply = calloc(n, sizeof(*reply))) == NULL) |
533 | return (PAM_CONV_ERR); | 569 | return (PAM_CONV_ERR); |
534 | memset(reply, 0, n * sizeof(*reply)); | ||
535 | 570 | ||
536 | for (i = 0; i < n; ++i) { | 571 | for (i = 0; i < n; ++i) { |
537 | switch (PAM_MSG_MEMBER(msg, i, msg_style)) { | 572 | switch (PAM_MSG_MEMBER(msg, i, msg_style)) { |
@@ -638,8 +673,11 @@ sshpam_init_ctx(Authctxt *authctxt) | |||
638 | int socks[2]; | 673 | int socks[2]; |
639 | 674 | ||
640 | debug3("PAM: %s entering", __func__); | 675 | debug3("PAM: %s entering", __func__); |
641 | /* Refuse to start if we don't have PAM enabled */ | 676 | /* |
642 | if (!options.use_pam) | 677 | * Refuse to start if we don't have PAM enabled or do_pam_account |
678 | * has previously failed. | ||
679 | */ | ||
680 | if (!options.use_pam || sshpam_account_status == 0) | ||
643 | return NULL; | 681 | return NULL; |
644 | 682 | ||
645 | /* Initialize PAM */ | 683 | /* Initialize PAM */ |
@@ -699,7 +737,7 @@ sshpam_query(void *ctx, char **name, char **info, | |||
699 | case PAM_PROMPT_ECHO_OFF: | 737 | case PAM_PROMPT_ECHO_OFF: |
700 | *num = 1; | 738 | *num = 1; |
701 | len = plen + mlen + 1; | 739 | len = plen + mlen + 1; |
702 | **prompts = xrealloc(**prompts, len); | 740 | **prompts = xrealloc(**prompts, 1, len); |
703 | strlcpy(**prompts + plen, msg, len - plen); | 741 | strlcpy(**prompts + plen, msg, len - plen); |
704 | plen += mlen; | 742 | plen += mlen; |
705 | **echo_on = (type == PAM_PROMPT_ECHO_ON); | 743 | **echo_on = (type == PAM_PROMPT_ECHO_ON); |
@@ -709,21 +747,25 @@ sshpam_query(void *ctx, char **name, char **info, | |||
709 | case PAM_TEXT_INFO: | 747 | case PAM_TEXT_INFO: |
710 | /* accumulate messages */ | 748 | /* accumulate messages */ |
711 | len = plen + mlen + 2; | 749 | len = plen + mlen + 2; |
712 | **prompts = xrealloc(**prompts, len); | 750 | **prompts = xrealloc(**prompts, 1, len); |
713 | strlcpy(**prompts + plen, msg, len - plen); | 751 | strlcpy(**prompts + plen, msg, len - plen); |
714 | plen += mlen; | 752 | plen += mlen; |
715 | strlcat(**prompts + plen, "\n", len - plen); | 753 | strlcat(**prompts + plen, "\n", len - plen); |
716 | plen++; | 754 | plen++; |
717 | xfree(msg); | 755 | xfree(msg); |
718 | break; | 756 | break; |
757 | case PAM_ACCT_EXPIRED: | ||
758 | sshpam_account_status = 0; | ||
759 | /* FALLTHROUGH */ | ||
719 | case PAM_AUTH_ERR: | 760 | case PAM_AUTH_ERR: |
720 | debug3("PAM: PAM_AUTH_ERR"); | 761 | debug3("PAM: %s", pam_strerror(sshpam_handle, type)); |
721 | if (**prompts != NULL && strlen(**prompts) != 0) { | 762 | if (**prompts != NULL && strlen(**prompts) != 0) { |
722 | *info = **prompts; | 763 | *info = **prompts; |
723 | **prompts = NULL; | 764 | **prompts = NULL; |
724 | *num = 0; | 765 | *num = 0; |
725 | **echo_on = 0; | 766 | **echo_on = 0; |
726 | ctxt->pam_done = -1; | 767 | ctxt->pam_done = -1; |
768 | xfree(msg); | ||
727 | return 0; | 769 | return 0; |
728 | } | 770 | } |
729 | /* FALLTHROUGH */ | 771 | /* FALLTHROUGH */ |
@@ -930,9 +972,8 @@ sshpam_tty_conv(int n, sshpam_const struct pam_message **msg, | |||
930 | if (n <= 0 || n > PAM_MAX_NUM_MSG || !isatty(STDIN_FILENO)) | 972 | if (n <= 0 || n > PAM_MAX_NUM_MSG || !isatty(STDIN_FILENO)) |
931 | return (PAM_CONV_ERR); | 973 | return (PAM_CONV_ERR); |
932 | 974 | ||
933 | if ((reply = malloc(n * sizeof(*reply))) == NULL) | 975 | if ((reply = calloc(n, sizeof(*reply))) == NULL) |
934 | return (PAM_CONV_ERR); | 976 | return (PAM_CONV_ERR); |
935 | memset(reply, 0, n * sizeof(*reply)); | ||
936 | 977 | ||
937 | for (i = 0; i < n; ++i) { | 978 | for (i = 0; i < n; ++i) { |
938 | switch (PAM_MSG_MEMBER(msg, i, msg_style)) { | 979 | switch (PAM_MSG_MEMBER(msg, i, msg_style)) { |