summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog7
-rw-r--r--acconfig.h5
-rw-r--r--configure.ac45
-rw-r--r--defines.h6
-rw-r--r--session.c80
5 files changed, 123 insertions, 20 deletions
diff --git a/ChangeLog b/ChangeLog
index 3f1a4cfe..6a32bc1a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+20030916
+ - (dtucker) [acconfig.h configure.ac defines.h session.c] Bug #252: Retrieve
+ PATH (or SUPATH) and UMASK from /etc/default/login on platforms that have it
+ (eg Solaris, Reliant Unix). Patch from Robert.Dahlem at siemens.com. ok djm@
+
20030914
- (dtucker) [Makefile regress/Makefile] Fix portability issues preventing
the regression tests from running with Solaris' make. Patch from Brian
@@ -1093,4 +1098,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.2991 2003/09/14 03:16:55 dtucker Exp $
+$Id: ChangeLog,v 1.2992 2003/09/16 01:52:19 dtucker Exp $
diff --git a/acconfig.h b/acconfig.h
index ea8fcb0b..9bfb9b6c 100644
--- a/acconfig.h
+++ b/acconfig.h
@@ -1,4 +1,4 @@
-/* $Id: acconfig.h,v 1.165 2003/09/08 21:35:17 tim Exp $ */
+/* $Id: acconfig.h,v 1.166 2003/09/16 01:52:19 dtucker Exp $ */
/*
* Copyright (c) 1999-2003 Damien Miller. All rights reserved.
@@ -359,6 +359,9 @@
/* Define in your struct dirent expects you to allocate extra space for d_name */
#undef BROKEN_ONE_BYTE_DIRENT_D_NAME
+/* Define if your system has /etc/default/login */
+#undef HAVE_ETC_DEFAULT_LOGIN
+
/* Define if your getopt(3) defines and uses optreset */
#undef HAVE_GETOPT_OPTRESET
diff --git a/configure.ac b/configure.ac
index 3d5389cc..ab630115 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,4 +1,4 @@
-# $Id: configure.ac,v 1.153 2003/09/13 01:15:15 tim Exp $
+# $Id: configure.ac,v 1.154 2003/09/16 01:52:19 dtucker Exp $
AC_INIT
AC_CONFIG_SRCDIR([ssh.c])
@@ -250,6 +250,7 @@ mips-sony-bsd|mips-sony-newsos4)
AC_DEFINE(LOCKED_PASSWD_STRING, "*LK*")
# Pushing STREAMS modules will cause sshd to acquire a controlling tty.
AC_DEFINE(SSHD_ACQUIRES_CTTY)
+ external_path_file=/etc/default/login
# hardwire lastlog location (can't detect it on some versions)
conf_lastlog_location="/var/adm/lastlog"
AC_MSG_CHECKING(for obsolete utmp and wtmp in solaris2.x)
@@ -286,6 +287,7 @@ mips-sony-bsd|mips-sony-newsos4)
AC_DEFINE(USE_PIPES)
AC_DEFINE(IP_TOS_IS_BROKEN)
AC_DEFINE(SSHD_ACQUIRES_CTTY)
+ external_path_file=/etc/default/login
# /usr/ucblib/libucb.a no longer needed on ReliantUNIX
# Attention: always take care to bind libsocket and libnsl before libc,
# otherwise you will find lots of "SIOCGPGRP errno 22" on syslog
@@ -2180,30 +2182,48 @@ else
)
fi
+# check for /etc/default/login and use it if present.
+AC_CHECK_FILE("/etc/default/login", [ external_path_file=/etc/default/login ])
+
+if test "x$external_path_file" = "x/etc/default/login"; then
+ AC_DEFINE(HAVE_ETC_DEFAULT_LOGIN)
+fi
+
dnl BSD systems use /etc/login.conf so --with-default-path= has no effect
if test $ac_cv_func_login_getcapbool = "yes" -a \
$ac_cv_header_login_cap_h = "yes" ; then
- USES_LOGIN_CONF=yes
+ external_path_file=/etc/login.conf
fi
+
# Whether to mess with the default path
SERVER_PATH_MSG="(default)"
AC_ARG_WITH(default-path,
[ --with-default-path= Specify default \$PATH environment for server],
[
- if test "$USES_LOGIN_CONF" = "yes" ; then
+ if test "x$external_path_file" = "x/etc/login.conf" ; then
AC_MSG_WARN([
--with-default-path=PATH has no effect on this system.
Edit /etc/login.conf instead.])
elif test "x$withval" != "xno" ; then
+ if ! test -z "$external_path_file" ; then
+ AC_MSG_WARN([
+--with-default-path=PATH will only be used if PATH is not defined in
+$external_path_file .])
+ fi
user_path="$withval"
SERVER_PATH_MSG="$withval"
fi
],
- [ if test "$USES_LOGIN_CONF" = "yes" ; then
- AC_MSG_WARN([Make sure the path to scp is in /etc/login.conf])
+ [ if test "x$external_path_file" = "x/etc/login.conf" ; then
+ AC_MSG_WARN([Make sure the path to scp is in /etc/login.conf])
else
- AC_TRY_RUN(
- [
+ if ! test -z "$external_path_file" ; then
+ AC_MSG_WARN([
+If PATH is defined in $external_path_file, ensure the path to scp is included,
+otherwise scp will not work.])
+ fi
+ AC_TRY_RUN(
+ [
/* find out what STDPATH is */
#include <stdio.h>
#ifdef HAVE_PATHS_H
@@ -2257,7 +2277,7 @@ main()
fi
fi ]
)
-if test "$USES_LOGIN_CONF" != "yes" ; then
+if test "x$external_path_file" != "x/etc/login.conf" ; then
AC_DEFINE_UNQUOTED(USER_PATH, "$user_path")
AC_SUBST(user_path)
fi
@@ -2627,10 +2647,15 @@ echo " Askpass program: $E"
echo " Manual pages: $F"
echo " PID file: $G"
echo " Privilege separation chroot path: $H"
-if test "$USES_LOGIN_CONF" = "yes" ; then
-echo " At runtime, sshd will use the path defined in /etc/login.conf"
+if test "x$external_path_file" = "x/etc/login.conf" ; then
+echo " At runtime, sshd will use the path defined in $external_path_file"
+echo " Make sure the path to scp is present, otherwise scp will not work"
else
echo " sshd default user PATH: $I"
+ if ! test -z "$external_path_file"; then
+echo " (If PATH is set in $external_path_file it will be used instead. If"
+echo " used, ensure the path to scp is present, otherwise scp will not work.)"
+ fi
fi
if test ! -z "$superuser_path" ; then
echo " sshd superuser user PATH: $J"
diff --git a/defines.h b/defines.h
index 7bff839c..e662966f 100644
--- a/defines.h
+++ b/defines.h
@@ -25,7 +25,7 @@
#ifndef _DEFINES_H
#define _DEFINES_H
-/* $Id: defines.h,v 1.102 2003/08/26 01:58:16 dtucker Exp $ */
+/* $Id: defines.h,v 1.103 2003/09/16 01:52:19 dtucker Exp $ */
/* Constants */
@@ -321,6 +321,10 @@ struct winsize {
# define _PATH_STDPATH "/usr/bin:/bin:/usr/sbin:/sbin"
#endif
+#ifndef SUPERUSER_PATH
+# define SUPERUSER_PATH _PATH_STDPATH
+#endif
+
#ifndef _PATH_DEVNULL
# define _PATH_DEVNULL "/dev/null"
#endif
diff --git a/session.c b/session.c
index 35328ecb..4497f5c0 100644
--- a/session.c
+++ b/session.c
@@ -802,6 +802,16 @@ child_set_env(char ***envp, u_int *envsizep, const char *name,
char **env;
/*
+ * If we're passed an uninitialized list, allocate a single null
+ * entry before continuing.
+ */
+ if (*envp == NULL && *envsizep == 0) {
+ *envp = xmalloc(sizeof(char *));
+ *envp[0] = NULL;
+ *envsizep = 1;
+ }
+
+ /*
* Find the slot where the value should be stored. If the variable
* already exists, we reuse the slot; otherwise we append a new slot
* at the end of the array, expanding if necessary.
@@ -877,6 +887,59 @@ read_environment_file(char ***env, u_int *envsize,
fclose(f);
}
+#ifdef HAVE_ETC_DEFAULT_LOGIN
+/*
+ * Return named variable from specified environment, or NULL if not present.
+ */
+static char *
+child_get_env(char **env, const char *name)
+{
+ int i;
+ size_t len;
+
+ len = strlen(name);
+ for (i=0; env[i] != NULL; i++)
+ if (strncmp(name, env[i], len) == 0 && env[i][len] == '=')
+ return(env[i] + len + 1);
+ return NULL;
+}
+
+/*
+ * Read /etc/default/login.
+ * We pick up the PATH (or SUPATH for root) and UMASK.
+ */
+static void
+read_etc_default_login(char ***env, u_int *envsize, uid_t uid)
+{
+ char **tmpenv = NULL, *var;
+ u_int i;
+ size_t tmpenvsize = 0;
+ mode_t mask;
+
+ /*
+ * We don't want to copy the whole file to the child's environment,
+ * so we use a temporary environment and copy the variables we're
+ * interested in.
+ */
+ read_environment_file(&tmpenv, &tmpenvsize, "/etc/default/login");
+
+ if (uid == 0)
+ var = child_get_env(tmpenv, "SUPATH");
+ else
+ var = child_get_env(tmpenv, "PATH");
+ if (var != NULL)
+ child_set_env(env, envsize, "PATH", var);
+
+ if ((var = child_get_env(tmpenv, "UMASK")) != NULL)
+ if (sscanf(var, "%5lo", &mask) == 1)
+ umask(mask);
+
+ for (i = 0; tmpenv[i] != NULL; i++)
+ xfree(tmpenv[i]);
+ xfree(tmpenv);
+}
+#endif /* HAVE_ETC_DEFAULT_LOGIN */
+
void copy_environment(char **source, char ***env, u_int *envsize)
{
char *var_name, *var_val;
@@ -905,7 +968,7 @@ do_setup_env(Session *s, const char *shell)
{
char buf[256];
u_int i, envsize;
- char **env, *laddr;
+ char **env, *laddr, *path = NULL;
struct passwd *pw = s->pw;
/* Initialize the environment. */
@@ -949,12 +1012,15 @@ do_setup_env(Session *s, const char *shell)
* needed for loading shared libraries. So the path better
* remains intact here.
*/
-# ifdef SUPERUSER_PATH
- child_set_env(&env, &envsize, "PATH",
- s->pw->pw_uid == 0 ? SUPERUSER_PATH : _PATH_STDPATH);
-# else
- child_set_env(&env, &envsize, "PATH", _PATH_STDPATH);
-# endif /* SUPERUSER_PATH */
+# ifdef HAVE_ETC_DEFAULT_LOGIN
+ read_etc_default_login(&env, &envsize, pw->pw_uid);
+ path = child_get_env(env, "PATH");
+# endif /* HAVE_ETC_DEFAULT_LOGIN */
+ if (path == NULL || *path == '\0') {
+ child_set_env(&env, &envsize, "PATH",
+ s->pw->pw_uid == 0 ?
+ SUPERUSER_PATH : _PATH_STDPATH);
+ }
# endif /* HAVE_CYGWIN */
#endif /* HAVE_LOGIN_CAP */