summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2003-11-17 21:41:42 +1100
committerDamien Miller <djm@mindrot.org>2003-11-17 21:41:42 +1100
commitc756e9b56e5b4649f120c417eb9bc99cf23db10f (patch)
tree70e3a7e326bddd3b46ebe457026e4f842bc3e7f9
parent9bdba70350919fced9ecdf5ca8a3709d22d69797 (diff)
- (djm) Export environment variables from authentication subprocess to
parent. Part of Bug #717
-rw-r--r--ChangeLog4
-rw-r--r--auth-pam.c83
-rw-r--r--auth-pam.h3
-rw-r--r--session.c7
4 files changed, 87 insertions, 10 deletions
diff --git a/ChangeLog b/ChangeLog
index b850f42d..bec42ac5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -45,6 +45,8 @@
return error on msg send/receive failure (rather than fatal); ok markus@
- (djm) Bug #632: Don't call pam_end indirectly from within kbd-int
conversation function
+ - (djm) Export environment variables from authentication subprocess to
+ parent. Part of Bug #717
20031115
- (dtucker) [regress/agent-ptrace.sh] Test for GDB output from Solaris and
@@ -1465,4 +1467,4 @@
- Fix sshd BindAddress and -b options for systems using fake-getaddrinfo.
Report from murple@murple.net, diagnosis from dtucker@zip.com.au
-$Id: ChangeLog,v 1.3110 2003/11/17 10:27:55 djm Exp $
+$Id: ChangeLog,v 1.3111 2003/11/17 10:41:42 djm Exp $
diff --git a/auth-pam.c b/auth-pam.c
index 4d2f9c59..92a3da40 100644
--- a/auth-pam.c
+++ b/auth-pam.c
@@ -31,7 +31,7 @@
/* Based on $FreeBSD: src/crypto/openssh/auth2-pam-freebsd.c,v 1.11 2003/03/31 13:48:18 des Exp $ */
#include "includes.h"
-RCSID("$Id: auth-pam.c,v 1.79 2003/11/17 10:27:55 djm Exp $");
+RCSID("$Id: auth-pam.c,v 1.80 2003/11/17 10:41:42 djm Exp $");
#ifdef USE_PAM
#include <security/pam_appl.h>
@@ -117,6 +117,7 @@ static int sshpam_authenticated = 0;
static int sshpam_new_authtok_reqd = 0;
static int sshpam_session_open = 0;
static int sshpam_cred_established = 0;
+static char **sshpam_env = NULL;
struct pam_ctxt {
sp_pthread_t pam_thread;
@@ -128,6 +129,51 @@ struct pam_ctxt {
static void sshpam_free_ctx(void *);
static struct pam_ctxt *cleanup_ctxt;
+/* Some PAM implementations don't implement this */
+#ifndef HAVE_PAM_GETENVLIST
+static char **
+pam_getenvlist(pam_handle_t *pamh)
+{
+ /*
+ * XXX - If necessary, we can still support envrionment passing
+ * for platforms without pam_getenvlist by searching for known
+ * env vars (e.g. KRB5CCNAME) from the PAM environment.
+ */
+ return NULL;
+}
+#endif
+
+/* Import regular and PAM environment from subprocess */
+static void
+import_environments(Buffer *b)
+{
+ char *env;
+ u_int i, num_env;
+ int err;
+
+ /* Import environment from subprocess */
+ num_env = buffer_get_int(b);
+ sshpam_env = xmalloc((num_env + 1) * sizeof(*sshpam_env));
+ debug3("PAM: num env strings %d", num_env);
+ for(i = 0; i < num_env; i++)
+ sshpam_env[i] = buffer_get_string(b, NULL);
+
+ sshpam_env[num_env] = NULL;
+
+ /* Import PAM environment from subprocess */
+ num_env = buffer_get_int(b);
+ debug("PAM: num PAM env strings %d", num_env);
+ for(i = 0; i < num_env; i++) {
+ env = buffer_get_string(b, NULL);
+
+ /* Errors are not fatal here */
+ if ((err = pam_putenv(sshpam_handle, env)) != PAM_SUCCESS) {
+ error("PAM: pam_putenv: %s",
+ pam_strerror(sshpam_handle, sshpam_err));
+ }
+ }
+}
+
/*
* Conversation function for authentication thread.
*/
@@ -220,10 +266,14 @@ sshpam_thread(void *ctxtp)
Buffer buffer;
struct pam_conv sshpam_conv;
#ifndef USE_POSIX_THREADS
+ extern char **environ;
+ char **env_from_pam;
+ u_int i;
const char *pam_user;
pam_get_item(sshpam_handle, PAM_USER, (const void **)&pam_user);
setproctitle("%s [pam]", pam_user);
+ environ[0] = NULL;
#endif
sshpam_conv.conv = sshpam_thread_conv;
@@ -238,6 +288,24 @@ sshpam_thread(void *ctxtp)
if (sshpam_err != PAM_SUCCESS)
goto auth_fail;
buffer_put_cstring(&buffer, "OK");
+
+#ifndef USE_POSIX_THREADS
+ /* Export any environment strings set in child */
+ for(i = 0; environ[i] != NULL; i++)
+ ; /* Count */
+ buffer_put_int(&buffer, i);
+ for(i = 0; environ[i] != NULL; i++)
+ buffer_put_cstring(&buffer, environ[i]);
+
+ /* Export any environment strings set by PAM in child */
+ env_from_pam = pam_getenvlist(sshpam_handle);
+ for(i = 0; env_from_pam != NULL && env_from_pam[i] != NULL; i++)
+ ; /* Count */
+ buffer_put_int(&buffer, i);
+ for(i = 0; env_from_pam != NULL && env_from_pam[i] != NULL; i++)
+ buffer_put_cstring(&buffer, env_from_pam[i]);
+#endif /* USE_POSIX_THREADS */
+
/* XXX - can't do much about an error here */
ssh_msg_send(ctxt->pam_csock, sshpam_err, &buffer);
buffer_free(&buffer);
@@ -440,6 +508,7 @@ sshpam_query(void *ctx, char **name, char **info,
**prompts = NULL;
}
if (type == PAM_SUCCESS) {
+ import_environments(&buffer);
*num = 0;
**echo_on = 0;
ctxt->pam_done = 1;
@@ -704,7 +773,6 @@ do_pam_chauthtok(void)
* modules can handle things like Kerberos/GSI credentials that appear
* during the ssh authentication process.
*/
-
int
do_pam_putenv(char *name, char *value)
{
@@ -731,14 +799,15 @@ print_pam_messages(void)
}
char **
+fetch_pam_child_environment(void)
+{
+ return sshpam_env;
+}
+
+char **
fetch_pam_environment(void)
{
-#ifdef HAVE_PAM_GETENVLIST
- debug("PAM: retrieving environment");
return (pam_getenvlist(sshpam_handle));
-#else
- return (NULL);
-#endif
}
void
diff --git a/auth-pam.h b/auth-pam.h
index 58176f01..fd62e953 100644
--- a/auth-pam.h
+++ b/auth-pam.h
@@ -1,4 +1,4 @@
-/* $Id: auth-pam.h,v 1.22 2003/10/07 01:30:16 dtucker Exp $ */
+/* $Id: auth-pam.h,v 1.23 2003/11/17 10:41:42 djm Exp $ */
/*
* Copyright (c) 2000 Damien Miller. All rights reserved.
@@ -42,6 +42,7 @@ void do_pam_chauthtok(void);
int do_pam_putenv(char *, char *);
void print_pam_messages(void);
char ** fetch_pam_environment(void);
+char ** fetch_pam_child_environment(void);
void free_pam_environment(char **);
void sshpam_thread_cleanup(void);
void sshpam_cleanup(void);
diff --git a/session.c b/session.c
index 0f803243..b1e6255f 100644
--- a/session.c
+++ b/session.c
@@ -1095,8 +1095,13 @@ do_setup_env(Session *s, const char *shell)
* been set by PAM.
*/
if (options.use_pam) {
- char **p = fetch_pam_environment();
+ char **p;
+
+ p = fetch_pam_child_environment();
+ copy_environment(p, &env, &envsize);
+ free_pam_environment(p);
+ p = fetch_pam_environment();
copy_environment(p, &env, &envsize);
free_pam_environment(p);
}