- (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@
This commit is contained in:
Darren Tucker 2003-09-16 11:52:19 +10:00
parent 7b6cb5c5ef
commit e1a790d0d1
5 changed files with 123 additions and 20 deletions

View File

@ -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 20030914
- (dtucker) [Makefile regress/Makefile] Fix portability issues preventing - (dtucker) [Makefile regress/Makefile] Fix portability issues preventing
the regression tests from running with Solaris' make. Patch from Brian 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. - Fix sshd BindAddress and -b options for systems using fake-getaddrinfo.
Report from murple@murple.net, diagnosis from dtucker@zip.com.au 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 $

View File

@ -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. * 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 */ /* Define in your struct dirent expects you to allocate extra space for d_name */
#undef BROKEN_ONE_BYTE_DIRENT_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 */ /* Define if your getopt(3) defines and uses optreset */
#undef HAVE_GETOPT_OPTRESET #undef HAVE_GETOPT_OPTRESET

View File

@ -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_INIT
AC_CONFIG_SRCDIR([ssh.c]) AC_CONFIG_SRCDIR([ssh.c])
@ -250,6 +250,7 @@ mips-sony-bsd|mips-sony-newsos4)
AC_DEFINE(LOCKED_PASSWD_STRING, "*LK*") AC_DEFINE(LOCKED_PASSWD_STRING, "*LK*")
# Pushing STREAMS modules will cause sshd to acquire a controlling tty. # Pushing STREAMS modules will cause sshd to acquire a controlling tty.
AC_DEFINE(SSHD_ACQUIRES_CTTY) AC_DEFINE(SSHD_ACQUIRES_CTTY)
external_path_file=/etc/default/login
# hardwire lastlog location (can't detect it on some versions) # hardwire lastlog location (can't detect it on some versions)
conf_lastlog_location="/var/adm/lastlog" conf_lastlog_location="/var/adm/lastlog"
AC_MSG_CHECKING(for obsolete utmp and wtmp in solaris2.x) 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(USE_PIPES)
AC_DEFINE(IP_TOS_IS_BROKEN) AC_DEFINE(IP_TOS_IS_BROKEN)
AC_DEFINE(SSHD_ACQUIRES_CTTY) AC_DEFINE(SSHD_ACQUIRES_CTTY)
external_path_file=/etc/default/login
# /usr/ucblib/libucb.a no longer needed on ReliantUNIX # /usr/ucblib/libucb.a no longer needed on ReliantUNIX
# Attention: always take care to bind libsocket and libnsl before libc, # Attention: always take care to bind libsocket and libnsl before libc,
# otherwise you will find lots of "SIOCGPGRP errno 22" on syslog # otherwise you will find lots of "SIOCGPGRP errno 22" on syslog
@ -2180,28 +2182,46 @@ else
) )
fi 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 dnl BSD systems use /etc/login.conf so --with-default-path= has no effect
if test $ac_cv_func_login_getcapbool = "yes" -a \ if test $ac_cv_func_login_getcapbool = "yes" -a \
$ac_cv_header_login_cap_h = "yes" ; then $ac_cv_header_login_cap_h = "yes" ; then
USES_LOGIN_CONF=yes external_path_file=/etc/login.conf
fi fi
# Whether to mess with the default path # Whether to mess with the default path
SERVER_PATH_MSG="(default)" SERVER_PATH_MSG="(default)"
AC_ARG_WITH(default-path, AC_ARG_WITH(default-path,
[ --with-default-path= Specify default \$PATH environment for server], [ --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([ AC_MSG_WARN([
--with-default-path=PATH has no effect on this system. --with-default-path=PATH has no effect on this system.
Edit /etc/login.conf instead.]) Edit /etc/login.conf instead.])
elif test "x$withval" != "xno" ; then 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" user_path="$withval"
SERVER_PATH_MSG="$withval" SERVER_PATH_MSG="$withval"
fi fi
], ],
[ if test "$USES_LOGIN_CONF" = "yes" ; then [ 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]) AC_MSG_WARN([Make sure the path to scp is in /etc/login.conf])
else else
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( AC_TRY_RUN(
[ [
/* find out what STDPATH is */ /* find out what STDPATH is */
@ -2257,7 +2277,7 @@ main()
fi fi
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_DEFINE_UNQUOTED(USER_PATH, "$user_path")
AC_SUBST(user_path) AC_SUBST(user_path)
fi fi
@ -2627,10 +2647,15 @@ echo " Askpass program: $E"
echo " Manual pages: $F" echo " Manual pages: $F"
echo " PID file: $G" echo " PID file: $G"
echo " Privilege separation chroot path: $H" echo " Privilege separation chroot path: $H"
if test "$USES_LOGIN_CONF" = "yes" ; then if test "x$external_path_file" = "x/etc/login.conf" ; then
echo " At runtime, sshd will use the path defined in /etc/login.conf" 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 else
echo " sshd default user PATH: $I" 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 fi
if test ! -z "$superuser_path" ; then if test ! -z "$superuser_path" ; then
echo " sshd superuser user PATH: $J" echo " sshd superuser user PATH: $J"

View File

@ -25,7 +25,7 @@
#ifndef _DEFINES_H #ifndef _DEFINES_H
#define _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 */ /* Constants */
@ -321,6 +321,10 @@ struct winsize {
# define _PATH_STDPATH "/usr/bin:/bin:/usr/sbin:/sbin" # define _PATH_STDPATH "/usr/bin:/bin:/usr/sbin:/sbin"
#endif #endif
#ifndef SUPERUSER_PATH
# define SUPERUSER_PATH _PATH_STDPATH
#endif
#ifndef _PATH_DEVNULL #ifndef _PATH_DEVNULL
# define _PATH_DEVNULL "/dev/null" # define _PATH_DEVNULL "/dev/null"
#endif #endif

View File

@ -801,6 +801,16 @@ child_set_env(char ***envp, u_int *envsizep, const char *name,
u_int i, namelen; u_int i, namelen;
char **env; 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 * Find the slot where the value should be stored. If the variable
* already exists, we reuse the slot; otherwise we append a new slot * already exists, we reuse the slot; otherwise we append a new slot
@ -877,6 +887,59 @@ read_environment_file(char ***env, u_int *envsize,
fclose(f); 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) void copy_environment(char **source, char ***env, u_int *envsize)
{ {
char *var_name, *var_val; char *var_name, *var_val;
@ -905,7 +968,7 @@ do_setup_env(Session *s, const char *shell)
{ {
char buf[256]; char buf[256];
u_int i, envsize; u_int i, envsize;
char **env, *laddr; char **env, *laddr, *path = NULL;
struct passwd *pw = s->pw; struct passwd *pw = s->pw;
/* Initialize the environment. */ /* Initialize the environment. */
@ -949,12 +1012,15 @@ do_setup_env(Session *s, const char *shell)
* needed for loading shared libraries. So the path better * needed for loading shared libraries. So the path better
* remains intact here. * remains intact here.
*/ */
# ifdef 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", child_set_env(&env, &envsize, "PATH",
s->pw->pw_uid == 0 ? SUPERUSER_PATH : _PATH_STDPATH); s->pw->pw_uid == 0 ?
# else SUPERUSER_PATH : _PATH_STDPATH);
child_set_env(&env, &envsize, "PATH", _PATH_STDPATH); }
# endif /* SUPERUSER_PATH */
# endif /* HAVE_CYGWIN */ # endif /* HAVE_CYGWIN */
#endif /* HAVE_LOGIN_CAP */ #endif /* HAVE_LOGIN_CAP */