Patches for OpenSSH 2.5.2p2: evaluate /etc/default/login, makefiles manpages

Edgar Hoch Edgar.Hoch at IMS.Uni-Stuttgart.DE
Fri Mar 30 02:32:25 EST 2001


Dear developers of OpenSSH,

first of all I want to thank you for your excellent work on OpenSSH!

I have compiled OpenSSH 2.5.2p2 on Sun Solaris 2.6 and Sun Solaris 8
and discovered some problems.

The first is that OpenSSH doesn't evaluate the file /etc/default/login
which contains some flags and parameters for the login process.
On important parameter is the default value for PATH.
As we want to set the default value of PATH after a login in one central
place,
we use /etc/default/login on Sun Solaris.

Ich have created a patch that evaluates those flags and parameters of
the file
/etc/default/login which are relevant for the login process after the
authentication is done. The patch is appended as an attachment.

Second I have made Sun Solaris packages for OpenSSH. To do this I
installed
OpenSSH in a temporary directory (e.g. /tmp/openssh-root/) and used this
tree
to create the Solaris package (similar like we do create rpm packages).
The problem is that I have to specify some variables for make to install
OpenSSH
in that temporary directory:

make prefix=/tmp/openssh-root/usr libexecdir=/tmp/openssh-root/usr/sbin 
mandir=/tmp/openssh-root/usr/man sysconfdir=/tmp/openssh-root/etc/ssh
install

In the default configuration the Makefile the goal 'manpages' is called
by
'install'. Then the created manpages get the temporary paths
(/tmp/openssh-root/...)
compiled in. That's not what I want, because when the Solaris package is
installed
then the files will be installed in /usr/bin, /usr/sbin etc. and not in
/tmp/openssh-root/usr/bin etc.

I created a patch that I appended as attachment. The patch changes
Makefile
so the goal 'manpages' is called by 'all'.

Another problem is that I have libz in /usr/local/lib as static and
shared library.
The linker prefers the shared version, so I have to explicitly specify
that it
should use the static version because /usr/local is nfs mounted and may
not
available when the host will boot and sshd will start. I found no
variable
or flag which I can give to 'configure' or to 'make' to do that. LIBS is
in the
wrong place in Makefile as '-lz' is given to the compiler/linker before
LIBS
in the created command line. The only solution for me was to change
Makefile
manually after 'configure' and before 'make'. I think there should be a
flag
that can be given to 'make' or 'configure' to link OpenSSH statically.

My hack:

    cp -p Makefile Makefile-before-changes
    sed -e '/^LIBS=/ s/-lz/-Xlinker -B -Xlinker static -lz -Xlinker -B
-Xlinker dynamic/' Makefile-before-changes >! Makefile


I would be glad if you would integrate the patch for /etc/default/login
and for
the manpages in Makefile in the next offical distribution.

Thanks in advance

Edgar Hoch

-- 
Edgar Hoch
Institut fuer maschinelle Sprachverarbeitung (IMS)
Universitaet Stuttgart, Germany
D-70174 Stuttgart, Azenbergstrasse 12
Tel.: +49-711-121-1350, Fax: +49-711-121-1366
EMail: Edgar.Hoch at ims.uni-stuttgart.de
WWW: http://www.ims.uni-stuttgart.de/~edgar/
-------------- next part --------------
--- session.c.orig-2.5.2p2	Thu Mar 22 01:58:27 2001
+++ session.c	Thu Mar 29 16:14:22 2001
@@ -58,6 +58,10 @@
 #include "canohost.h"
 #include "session.h"
 
+#ifdef HAVE_ULIMIT_H
+#include <ulimit.h>
+#endif /* ULIMIT_H */
+
 #ifdef WITH_IRIX_PROJECT
 #include <proj.h>
 #endif /* WITH_IRIX_PROJECT */
@@ -915,6 +919,150 @@
 }
 #endif
 
+/*
+ * Get the value to the variable 'name' in the given environment 'env'.
+ * If the variable isn't defined, return NULL.
+ */
+char *get_environment_value(char **env, const char *name)
+{
+	u_int i, namelen;
+
+	namelen = strlen(name);
+	for (i = 0; env[i]; i++)
+		if (strncmp(env[i], name, namelen) == 0 && env[i][namelen] == '=')
+			break;
+	if (env[i])
+		return &env[i][namelen + 1];
+	else
+		return NULL;
+}
+
+#define ETC_DEFAULT_LOGIN_FILENAME "/etc/default/login"
+/*
+ * Sun Solaris uses the file ETC_DEFAULT_LOGIN_FILENAME
+ * to specify some flags and environment variables for the login process.
+ * This file consist of empty lines, comments (line starts with '#')
+ * and assignments of the form name=value.  No other forms are allowed.
+ *
+ * This procedure read this file and set the proper variables.
+ * The arguments are pointers to the current environment and its size.
+ * This environment will be changed according to the contents of
+ * the file ETC_DEFAULT_LOGIN_FILENAME.
+ * 'shell' is the default shell of the user.
+ *
+ * This procedure also sets environment variable SHELL
+ * if it isn't prohibited by a entry in file ETC_DEFAULT_LOGIN_FILENAME.
+ *
+ * Other flags in file ETC_DEFAULT_LOGIN_FILENAME that cause actions
+ * other than setting environment variables,
+ * setting the umask and ulimit
+ * will not be processed.
+ */
+void do_etc_default_login(char ***env, int *envsize, const char *shell,
+			  const uid_t uid)
+{
+	char **default_login_env;
+	u_int default_login_env_size;
+	char *value;
+
+	/*
+	 * Read the assignments in file ETC_DEFAULT_LOGIN_FILENAME
+         * into the temporary environment default_login_env.
+	 */
+	default_login_env_size = 20;
+	default_login_env = xmalloc(default_login_env_size * sizeof(char *));
+	default_login_env[0] = NULL;
+	read_environment_file(&default_login_env, &default_login_env_size,
+			      ETC_DEFAULT_LOGIN_FILENAME);
+
+	/*
+	 * For each known flag in file ETC_DEFAULT_LOGIN_FILENAME
+	 * if it is defined then set the proper environment variables.
+	 */
+
+	/* Set environment variable SHELL only if ALTSHELL has value "YES". */
+	value = get_environment_value(default_login_env, "ALTSHELL");
+	if (value == NULL) {
+		/* Normal systems set SHELL by default. */
+		child_set_env(env, envsize, "SHELL", shell);
+	} else if (strcmp(value, "YES") == 0) {
+		child_set_env(env, envsize, "SHELL", shell);
+	}
+
+	/*
+	 * If  the user is root and SUPATH is defined,
+	 * set environment variable PATH to the value of SUPATH.
+	 * Else if PATH is defined then
+	 * set environment variable PATH to the value of PATH.
+	 */
+	if (uid == 0) {
+		value = get_environment_value(default_login_env, "SUPATH");
+		if (value != NULL)
+			child_set_env(env, envsize, "PATH", value);
+	} else {
+		value = get_environment_value(default_login_env, "PATH");
+		if (value != NULL)
+			child_set_env(env, envsize, "PATH", value);
+	}
+
+	/*
+	 * If TIMEZONE is defined then set environment variable TZ
+	 * if it isn't already defined in the environment.
+	 */
+	if (get_environment_value(*env, "TZ") == NULL) {
+		value = get_environment_value(default_login_env, "TIMEZONE");
+		if (value != NULL)
+			child_set_env(env, envsize, "TZ", value);
+	}
+
+	/* If HZ is defined then set environment variable HZ. */
+	value = get_environment_value(default_login_env, "HZ");
+	if (value != NULL)
+		child_set_env(env, envsize, "HZ", value);
+
+	/* If UMASK is defined then set the default umask. */
+	value = get_environment_value(default_login_env, "UMASK");
+	if (value != NULL) {
+		int i;
+		mode_t default_umask = 0;
+		/* UMASK must contain only digits 0-7. */
+		for (i = 0;
+		     value[i] && isdigit((int)value[i]) && value[i] != '8' && value[i] != '9';
+		     i++)
+			default_umask = default_umask * 8 + value[i] - '0';
+		/* Set umask only if the value have had right syntax. */
+		if (value[i] == NULL)
+			umask(default_umask);
+	}
+
+#ifdef HAVE_ULIMIT_H
+	/* Set the file size limit if ULIMIT is defined. */
+	value = get_environment_value(default_login_env, "ULIMIT");
+	if (value != NULL && atoi(value) > 0)
+		ulimit(UL_SETFSIZE, atoi(value));
+#endif /* HAVE_ULIMIT_H */
+
+	/*
+	 * The following flags from file ETC_DEFAULT_LOGIN_FILENAME
+	 * are not processed by this procedure:
+	 * CONSOLE
+	 * PASSREQ
+	 * TIMEOUT
+	 * SYSLOG
+	 * SLEEPTIME
+	 * RETRIES
+	 * SYSLOG_FAILED_LOGINS
+	 */
+
+	/* Clean up: Free the temporary environment. */
+	{
+		u_int i;
+		for (i = 0; default_login_env[i]; i++)
+			xfree(default_login_env[i]);
+	}
+	xfree(default_login_env);
+}
+
 #if defined(HAVE_GETUSERATTR)
 /*
  * AIX-specific login initialisation
@@ -1213,12 +1361,26 @@
 # endif /* HAVE_CYGWIN */
 #endif /* HAVE_LOGIN_CAP */
 
-		snprintf(buf, sizeof buf, "%.200s/%.50s",
-			 _PATH_MAILDIR, pw->pw_name);
+		/*
+		 * Set environment variable MAIL.
+		 * _PATH_MAILDIR may have a '/' appended (e.g. on Solaris)
+		 * or have no '/' at the end.
+		 */
+		snprintf(buf, sizeof buf, "%.200s%s%.50s",
+			 _PATH_MAILDIR,
+			 strlen(_PATH_MAILDIR) > 0
+			 && _PATH_MAILDIR[strlen(_PATH_MAILDIR)-1] == '/'
+			 ? "" : "/",
+			 pw->pw_name);
 		child_set_env(&env, &envsize, "MAIL", buf);
 
-		/* Normal systems set SHELL by default. */
-		child_set_env(&env, &envsize, "SHELL", shell);
+		/*
+		 * Process file /etc/default/login if available.
+		 * This procedure also sets environment variable SHELL
+		 * if it isn't prohibited by a entry in file
+		 * /etc/default/login.
+		 */
+		do_etc_default_login(&env, &envsize, shell, pw->pw_uid);
 	}
 	if (getenv("TZ"))
 		child_set_env(&env, &envsize, "TZ", getenv("TZ"));
@@ -1282,7 +1444,7 @@
 
 	/* read $HOME/.ssh/environment. */
 	if (!options.use_login) {
-		snprintf(buf, sizeof buf, "%.200s/.ssh/environment",
+		snprintf(buf, sizeof buf, "%.512s/.ssh/environment",
 		    pw->pw_dir);
 		read_environment_file(&env, &envsize, buf);
 	}
@@ -1290,7 +1452,7 @@
 		/* dump the environment */
 		fprintf(stderr, "Environment:\n");
 		for (i = 0; env[i]; i++)
-			fprintf(stderr, "  %.200s\n", env[i]);
+			fprintf(stderr, "  %.512s\n", env[i]);
 	}
 	/* we have to stash the hostname before we close our socket. */
 	if (options.use_login)
--- configure.in.orig-2.5.2p2	Mon Mar 19 00:09:28 2001
+++ configure.in	Wed Mar 21 17:20:12 2001
@@ -368,7 +368,7 @@
 AC_FUNC_STRFTIME
 
 # Checks for header files.
-AC_CHECK_HEADERS(bstring.h endian.h floatingpoint.h getopt.h glob.h lastlog.h limits.h login.h login_cap.h maillock.h netdb.h netgroup.h netinet/in_systm.h paths.h poll.h pty.h regex.h shadow.h security/pam_appl.h sys/bitypes.h sys/bsdtty.h sys/cdefs.h sys/poll.h sys/queue.h sys/select.h sys/stat.h sys/stropts.h sys/sysmacros.h sys/time.h sys/ttcompat.h sys/un.h stddef.h time.h ttyent.h usersec.h util.h utime.h utmp.h utmpx.h vis.h)
+AC_CHECK_HEADERS(bstring.h endian.h floatingpoint.h getopt.h glob.h lastlog.h limits.h login.h login_cap.h maillock.h netdb.h netgroup.h netinet/in_systm.h paths.h poll.h pty.h regex.h shadow.h security/pam_appl.h sys/bitypes.h sys/bsdtty.h sys/cdefs.h sys/poll.h sys/queue.h sys/select.h sys/stat.h sys/stropts.h sys/sysmacros.h sys/time.h sys/ttcompat.h sys/un.h stddef.h time.h ttyent.h ulimit.h usersec.h util.h utime.h utmp.h utmpx.h vis.h)
 
 # Check for ALTDIRFUNC glob() extension
 AC_MSG_CHECKING(for GLOB_ALTDIRFUNC support)
--- configure.orig-2.5.2p2	Thu Mar 22 06:07:06 2001
+++ configure	Wed Mar 21 17:52:23 2001
@@ -2940,7 +2940,7 @@
 
 
 # Checks for header files.
-for ac_hdr in bstring.h endian.h floatingpoint.h getopt.h glob.h lastlog.h limits.h login.h login_cap.h maillock.h netdb.h netgroup.h netinet/in_systm.h paths.h poll.h pty.h regex.h shadow.h security/pam_appl.h sys/bitypes.h sys/bsdtty.h sys/cdefs.h sys/poll.h sys/queue.h sys/select.h sys/stat.h sys/stropts.h sys/sysmacros.h sys/time.h sys/ttcompat.h sys/un.h stddef.h time.h ttyent.h usersec.h util.h utime.h utmp.h utmpx.h vis.h
+for ac_hdr in bstring.h endian.h floatingpoint.h getopt.h glob.h lastlog.h limits.h login.h login_cap.h maillock.h netdb.h netgroup.h netinet/in_systm.h paths.h poll.h pty.h regex.h shadow.h security/pam_appl.h sys/bitypes.h sys/bsdtty.h sys/cdefs.h sys/poll.h sys/queue.h sys/select.h sys/stat.h sys/stropts.h sys/sysmacros.h sys/time.h sys/ttcompat.h sys/un.h stddef.h time.h ttyent.h ulimit.h usersec.h util.h utime.h utmp.h utmpx.h vis.h
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-------------- next part --------------
--- Makefile.in.orig-2.5.2p2	Wed Mar 21 03:12:12 2001
+++ Makefile.in	Thu Mar 22 16:41:18 2001
@@ -73,7 +73,7 @@
 
 FIXPATHSCMD	= $(PERL) $(srcdir)/fixpaths $(PATHSUBS)
 
-all: $(CONFIGFILES) $(TARGETS) 
+all: $(CONFIGFILES) $(TARGETS) manpages
 
 manpages: $(MANPAGES)
 
@@ -151,7 +151,7 @@
 distprep: catman-do
 	autoreconf
 
-install: manpages $(TARGETS) install-files host-key
+install: $(TARGETS) install-files host-key
 
 install-files:
 	$(srcdir)/mkinstalldirs $(DESTDIR)$(bindir)


More information about the openssh-unix-dev mailing list