diff options
-rw-r--r-- | ChangeLog | 4 | ||||
-rw-r--r-- | auth-pam.c | 83 | ||||
-rw-r--r-- | auth-pam.h | 3 | ||||
-rw-r--r-- | session.c | 7 |
4 files changed, 87 insertions, 10 deletions
@@ -45,6 +45,8 @@ | |||
45 | return error on msg send/receive failure (rather than fatal); ok markus@ | 45 | return error on msg send/receive failure (rather than fatal); ok markus@ |
46 | - (djm) Bug #632: Don't call pam_end indirectly from within kbd-int | 46 | - (djm) Bug #632: Don't call pam_end indirectly from within kbd-int |
47 | conversation function | 47 | conversation function |
48 | - (djm) Export environment variables from authentication subprocess to | ||
49 | parent. Part of Bug #717 | ||
48 | 50 | ||
49 | 20031115 | 51 | 20031115 |
50 | - (dtucker) [regress/agent-ptrace.sh] Test for GDB output from Solaris and | 52 | - (dtucker) [regress/agent-ptrace.sh] Test for GDB output from Solaris and |
@@ -1465,4 +1467,4 @@ | |||
1465 | - Fix sshd BindAddress and -b options for systems using fake-getaddrinfo. | 1467 | - Fix sshd BindAddress and -b options for systems using fake-getaddrinfo. |
1466 | Report from murple@murple.net, diagnosis from dtucker@zip.com.au | 1468 | Report from murple@murple.net, diagnosis from dtucker@zip.com.au |
1467 | 1469 | ||
1468 | $Id: ChangeLog,v 1.3110 2003/11/17 10:27:55 djm Exp $ | 1470 | $Id: ChangeLog,v 1.3111 2003/11/17 10:41:42 djm Exp $ |
diff --git a/auth-pam.c b/auth-pam.c index 4d2f9c597..92a3da406 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.79 2003/11/17 10:27:55 djm Exp $"); | 34 | RCSID("$Id: auth-pam.c,v 1.80 2003/11/17 10:41:42 djm Exp $"); |
35 | 35 | ||
36 | #ifdef USE_PAM | 36 | #ifdef USE_PAM |
37 | #include <security/pam_appl.h> | 37 | #include <security/pam_appl.h> |
@@ -117,6 +117,7 @@ static int sshpam_authenticated = 0; | |||
117 | static int sshpam_new_authtok_reqd = 0; | 117 | static int sshpam_new_authtok_reqd = 0; |
118 | static int sshpam_session_open = 0; | 118 | static int sshpam_session_open = 0; |
119 | static int sshpam_cred_established = 0; | 119 | static int sshpam_cred_established = 0; |
120 | static char **sshpam_env = NULL; | ||
120 | 121 | ||
121 | struct pam_ctxt { | 122 | struct pam_ctxt { |
122 | sp_pthread_t pam_thread; | 123 | sp_pthread_t pam_thread; |
@@ -128,6 +129,51 @@ struct pam_ctxt { | |||
128 | static void sshpam_free_ctx(void *); | 129 | static void sshpam_free_ctx(void *); |
129 | static struct pam_ctxt *cleanup_ctxt; | 130 | static struct pam_ctxt *cleanup_ctxt; |
130 | 131 | ||
132 | /* Some PAM implementations don't implement this */ | ||
133 | #ifndef HAVE_PAM_GETENVLIST | ||
134 | static char ** | ||
135 | pam_getenvlist(pam_handle_t *pamh) | ||
136 | { | ||
137 | /* | ||
138 | * XXX - If necessary, we can still support envrionment passing | ||
139 | * for platforms without pam_getenvlist by searching for known | ||
140 | * env vars (e.g. KRB5CCNAME) from the PAM environment. | ||
141 | */ | ||
142 | return NULL; | ||
143 | } | ||
144 | #endif | ||
145 | |||
146 | /* Import regular and PAM environment from subprocess */ | ||
147 | static void | ||
148 | import_environments(Buffer *b) | ||
149 | { | ||
150 | char *env; | ||
151 | u_int i, num_env; | ||
152 | int err; | ||
153 | |||
154 | /* Import environment from subprocess */ | ||
155 | num_env = buffer_get_int(b); | ||
156 | sshpam_env = xmalloc((num_env + 1) * sizeof(*sshpam_env)); | ||
157 | debug3("PAM: num env strings %d", num_env); | ||
158 | for(i = 0; i < num_env; i++) | ||
159 | sshpam_env[i] = buffer_get_string(b, NULL); | ||
160 | |||
161 | sshpam_env[num_env] = NULL; | ||
162 | |||
163 | /* Import PAM environment from subprocess */ | ||
164 | num_env = buffer_get_int(b); | ||
165 | debug("PAM: num PAM env strings %d", num_env); | ||
166 | for(i = 0; i < num_env; i++) { | ||
167 | env = buffer_get_string(b, NULL); | ||
168 | |||
169 | /* Errors are not fatal here */ | ||
170 | if ((err = pam_putenv(sshpam_handle, env)) != PAM_SUCCESS) { | ||
171 | error("PAM: pam_putenv: %s", | ||
172 | pam_strerror(sshpam_handle, sshpam_err)); | ||
173 | } | ||
174 | } | ||
175 | } | ||
176 | |||
131 | /* | 177 | /* |
132 | * Conversation function for authentication thread. | 178 | * Conversation function for authentication thread. |
133 | */ | 179 | */ |
@@ -220,10 +266,14 @@ sshpam_thread(void *ctxtp) | |||
220 | Buffer buffer; | 266 | Buffer buffer; |
221 | struct pam_conv sshpam_conv; | 267 | struct pam_conv sshpam_conv; |
222 | #ifndef USE_POSIX_THREADS | 268 | #ifndef USE_POSIX_THREADS |
269 | extern char **environ; | ||
270 | char **env_from_pam; | ||
271 | u_int i; | ||
223 | const char *pam_user; | 272 | const char *pam_user; |
224 | 273 | ||
225 | pam_get_item(sshpam_handle, PAM_USER, (const void **)&pam_user); | 274 | pam_get_item(sshpam_handle, PAM_USER, (const void **)&pam_user); |
226 | setproctitle("%s [pam]", pam_user); | 275 | setproctitle("%s [pam]", pam_user); |
276 | environ[0] = NULL; | ||
227 | #endif | 277 | #endif |
228 | 278 | ||
229 | sshpam_conv.conv = sshpam_thread_conv; | 279 | sshpam_conv.conv = sshpam_thread_conv; |
@@ -238,6 +288,24 @@ sshpam_thread(void *ctxtp) | |||
238 | if (sshpam_err != PAM_SUCCESS) | 288 | if (sshpam_err != PAM_SUCCESS) |
239 | goto auth_fail; | 289 | goto auth_fail; |
240 | buffer_put_cstring(&buffer, "OK"); | 290 | buffer_put_cstring(&buffer, "OK"); |
291 | |||
292 | #ifndef USE_POSIX_THREADS | ||
293 | /* Export any environment strings set in child */ | ||
294 | for(i = 0; environ[i] != NULL; i++) | ||
295 | ; /* Count */ | ||
296 | buffer_put_int(&buffer, i); | ||
297 | for(i = 0; environ[i] != NULL; i++) | ||
298 | buffer_put_cstring(&buffer, environ[i]); | ||
299 | |||
300 | /* Export any environment strings set by PAM in child */ | ||
301 | env_from_pam = pam_getenvlist(sshpam_handle); | ||
302 | for(i = 0; env_from_pam != NULL && env_from_pam[i] != NULL; i++) | ||
303 | ; /* Count */ | ||
304 | buffer_put_int(&buffer, i); | ||
305 | for(i = 0; env_from_pam != NULL && env_from_pam[i] != NULL; i++) | ||
306 | buffer_put_cstring(&buffer, env_from_pam[i]); | ||
307 | #endif /* USE_POSIX_THREADS */ | ||
308 | |||
241 | /* XXX - can't do much about an error here */ | 309 | /* XXX - can't do much about an error here */ |
242 | ssh_msg_send(ctxt->pam_csock, sshpam_err, &buffer); | 310 | ssh_msg_send(ctxt->pam_csock, sshpam_err, &buffer); |
243 | buffer_free(&buffer); | 311 | buffer_free(&buffer); |
@@ -440,6 +508,7 @@ sshpam_query(void *ctx, char **name, char **info, | |||
440 | **prompts = NULL; | 508 | **prompts = NULL; |
441 | } | 509 | } |
442 | if (type == PAM_SUCCESS) { | 510 | if (type == PAM_SUCCESS) { |
511 | import_environments(&buffer); | ||
443 | *num = 0; | 512 | *num = 0; |
444 | **echo_on = 0; | 513 | **echo_on = 0; |
445 | ctxt->pam_done = 1; | 514 | ctxt->pam_done = 1; |
@@ -704,7 +773,6 @@ do_pam_chauthtok(void) | |||
704 | * modules can handle things like Kerberos/GSI credentials that appear | 773 | * modules can handle things like Kerberos/GSI credentials that appear |
705 | * during the ssh authentication process. | 774 | * during the ssh authentication process. |
706 | */ | 775 | */ |
707 | |||
708 | int | 776 | int |
709 | do_pam_putenv(char *name, char *value) | 777 | do_pam_putenv(char *name, char *value) |
710 | { | 778 | { |
@@ -731,14 +799,15 @@ print_pam_messages(void) | |||
731 | } | 799 | } |
732 | 800 | ||
733 | char ** | 801 | char ** |
802 | fetch_pam_child_environment(void) | ||
803 | { | ||
804 | return sshpam_env; | ||
805 | } | ||
806 | |||
807 | char ** | ||
734 | fetch_pam_environment(void) | 808 | fetch_pam_environment(void) |
735 | { | 809 | { |
736 | #ifdef HAVE_PAM_GETENVLIST | ||
737 | debug("PAM: retrieving environment"); | ||
738 | return (pam_getenvlist(sshpam_handle)); | 810 | return (pam_getenvlist(sshpam_handle)); |
739 | #else | ||
740 | return (NULL); | ||
741 | #endif | ||
742 | } | 811 | } |
743 | 812 | ||
744 | void | 813 | void |
diff --git a/auth-pam.h b/auth-pam.h index 58176f013..fd62e9534 100644 --- a/auth-pam.h +++ b/auth-pam.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $Id: auth-pam.h,v 1.22 2003/10/07 01:30:16 dtucker Exp $ */ | 1 | /* $Id: auth-pam.h,v 1.23 2003/11/17 10:41:42 djm Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Copyright (c) 2000 Damien Miller. All rights reserved. | 4 | * Copyright (c) 2000 Damien Miller. All rights reserved. |
@@ -42,6 +42,7 @@ void do_pam_chauthtok(void); | |||
42 | int do_pam_putenv(char *, char *); | 42 | int do_pam_putenv(char *, char *); |
43 | void print_pam_messages(void); | 43 | void print_pam_messages(void); |
44 | char ** fetch_pam_environment(void); | 44 | char ** fetch_pam_environment(void); |
45 | char ** fetch_pam_child_environment(void); | ||
45 | void free_pam_environment(char **); | 46 | void free_pam_environment(char **); |
46 | void sshpam_thread_cleanup(void); | 47 | void sshpam_thread_cleanup(void); |
47 | void sshpam_cleanup(void); | 48 | void sshpam_cleanup(void); |
@@ -1095,8 +1095,13 @@ do_setup_env(Session *s, const char *shell) | |||
1095 | * been set by PAM. | 1095 | * been set by PAM. |
1096 | */ | 1096 | */ |
1097 | if (options.use_pam) { | 1097 | if (options.use_pam) { |
1098 | char **p = fetch_pam_environment(); | 1098 | char **p; |
1099 | |||
1100 | p = fetch_pam_child_environment(); | ||
1101 | copy_environment(p, &env, &envsize); | ||
1102 | free_pam_environment(p); | ||
1099 | 1103 | ||
1104 | p = fetch_pam_environment(); | ||
1100 | copy_environment(p, &env, &envsize); | 1105 | copy_environment(p, &env, &envsize); |
1101 | free_pam_environment(p); | 1106 | free_pam_environment(p); |
1102 | } | 1107 | } |