Edgar Hoch
2001-Mar-29 16:32 UTC
Patches for OpenSSH 2.5.2p2: evaluate /etc/default/login, makefiles manpages
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)
Christopher Linn
2001-Mar-29 17:10 UTC
Patches for OpenSSH 2.5.2p2: evaluate /etc/default/login, makefiles manpages
hi edgar, i am not an openssh developr, however i am working on building openssh solaris packages also. firstly, thank you very much for your default login work! now, i think you are doing your makes incorrectly: On Thu, Mar 29, 2001 at 06:32:25PM +0200, Edgar Hoch wrote: [...]> 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[...] this is not the way you want to do this; i belive that will mess up all the pathnames embedded in your binaries and manpages. there is a make variable in the openssh Makefile that you use, "DESTDIR", to accomplish the install into the tmp package building directory. ALL your --prefix etc should be set exactly as though you were installing on the build machine itself, this makes the embedded pathnames all correct. then do your make install like: # make DESTDIR=/tmp/openssh-root install this will do the actual install in your "fake" area, where you can then proceed to install prngd there if you want, and then run pkgproto and pkgmk in /tmp/openssh-root as you would normally do. regards, chris -- Christopher Linn, <celinn at mtu.edu> | By no means shall either the CEC Staff System Administrator | or MTU be held in any way liable Center for Experimental Computation | for any opinions or conjecture I Michigan Technological University | hold to or imply to hold herein.
Christopher Linn
2001-Mar-29 18:19 UTC
Patches for OpenSSH 2.5.2p2: evaluate /etc/default/login, makefiles manpages
hello again, i belive i have made a mistake: On Thu, Mar 29, 2001 at 12:10:49PM -0500, Christopher Linn wrote: [...]> # make DESTDIR=/tmp/openssh-root installis incorrect. that is the correct syntax for OpenBSD make. the correct syntax for /usr/ccs/bin/make on solaris is: # make install DESTDIR=/tmp/openssh-root my apologies. cheers, chris -- Christopher Linn, <celinn at mtu.edu> | By no means shall either the CEC Staff System Administrator | or MTU be held in any way liable Center for Experimental Computation | for any opinions or conjecture I Michigan Technological University | hold to or imply to hold herein.
Christopher Linn
2001-Mar-30 00:20 UTC
Patches for OpenSSH 2.5.2p2: evaluate /etc/default/login, makefiles manpages
edgar, for the second time i must apologize.> > > 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 > > [...] > > > > this is not the way you want to do this; i belive that will mess up > > all the pathnames embedded in your binaries and manpages.i was terribly wrong about this, you are actually doing correct variable substitution passing to make to the install target. this would not mess up any embedded pathnames. further,> # make DESTDIR=/tmp/openssh-root install > > is incorrect. that is the correct syntax for OpenBSD make. the correct > syntax for /usr/ccs/bin/make on solaris is: > > # make install DESTDIR=/tmp/openssh-root > > my apologies.i have since tried this both ways, and /usr/ccs/bin/make will do the correct thing when the make target is either before or after the variable-passing args to make, although i get make errors failing on the "host-key" make target when using your prefix, libexecdir, mandir sysconfdir set of make variables. in my own defense, the solaris 2.6 make(1S) manpage places the target before the variable substitution ;*) however, i would still reccommend the use of the DESTDIR make variable built-in to the OpenSSH Makefile, because this is exactly what it was designed to do. i am terribly embarrassed and humbled. again, my apologies. sincerely, chris -- Christopher Linn, <celinn at mtu.edu> | By no means shall either the CEC Staff System Administrator | or MTU be held in any way liable Center for Experimental Computation | for any opinions or conjecture I Michigan Technological University | hold to or imply to hold herein.