Index: security/openssh-portable/files/patch-session.c =================================================================== --- security/openssh-portable/files/patch-session.c +++ security/openssh-portable/files/patch-session.c @@ -15,59 +15,90 @@ --- session.c.orig 2021-04-15 20:55:25.000000000 -0700 +++ session.c 2021-04-27 13:11:13.515917000 -0700 -@@ -942,7 +942,7 @@ read_etc_default_login(char ***env, u_int *envsize, ui - } - #endif /* HAVE_ETC_DEFAULT_LOGIN */ +@@ -939,6 +939,9 @@ do_setup_env(struct ssh *ssh, Session *s, const char * + struct passwd *pw = s->pw; + #if !defined (HAVE_LOGIN_CAP) && !defined (HAVE_CYGWIN) + char *path = NULL; ++#else ++ extern char **environ; ++ char **senv, **var, *val; + #endif --#if defined(USE_PAM) || defined(HAVE_CYGWIN) -+#if defined(USE_PAM) || defined(HAVE_CYGWIN) || defined(HAVE_LOGIN_CAP) - static void - copy_environment_denylist(char **source, char ***env, u_int *envsize, - const char *denylist) -@@ -1052,7 +1052,8 @@ do_setup_env(struct ssh *ssh, Session *s, const char * + /* Initialize the environment. */ +@@ -960,6 +963,9 @@ do_setup_env(struct ssh *ssh, Session *s, const char * + } + #endif + ++ if (getenv("TZ")) ++ child_set_env(&env, &envsize, "TZ", getenv("TZ")); ++ + #ifdef GSSAPI + /* Allow any GSSAPI methods that we've used to alter + * the child's environment as they see fit +@@ -977,11 +983,30 @@ do_setup_env(struct ssh *ssh, Session *s, const char * + child_set_env(&env, &envsize, "LOGIN", pw->pw_name); + #endif + child_set_env(&env, &envsize, "HOME", pw->pw_dir); ++ snprintf(buf, sizeof buf, "%.200s/%.50s", _PATH_MAILDIR, pw->pw_name); ++ child_set_env(&env, &envsize, "MAIL", buf); + #ifdef HAVE_LOGIN_CAP +- if (setusercontext(lc, pw, pw->pw_uid, LOGIN_SETPATH) < 0) +- child_set_env(&env, &envsize, "PATH", _PATH_STDPATH); +- else +- child_set_env(&env, &envsize, "PATH", getenv("PATH")); ++ child_set_env(&env, &envsize, "PATH", _PATH_STDPATH); ++ child_set_env(&env, &envsize, "TERM", "su"); ++ /* ++ * Temporarily swap out our real environment with an empty one, ++ * let setusercontext() apply any environment variables defined ++ * for the user's login class, copy those variables to the child, ++ * free the temporary environment, and restore the original. ++ */ ++ senv = environ; ++ environ = xmalloc(sizeof(*environ)); ++ *environ = NULL; ++ (void)setusercontext(lc, pw, pw->pw_uid, LOGIN_SETENV|LOGIN_SETPATH); ++ for (var = environ; *var != NULL; ++var) { ++ if ((val = strchr(*var, '=')) != NULL) { ++ *val++ = '\0'; ++ child_set_env(&env, &envsize, *var, val); ++ } ++ free(*var); ++ } ++ free(environ); ++ environ = senv; + #else /* HAVE_LOGIN_CAP */ + # ifndef HAVE_CYGWIN + /* +@@ -1001,17 +1026,9 @@ do_setup_env(struct ssh *ssh, Session *s, const char * # endif /* HAVE_CYGWIN */ #endif /* HAVE_LOGIN_CAP */ - if (!options.use_pam) { -+ /* FreeBSD PAM doesn't set default "MAIL" */ -+ if (1 || !options.use_pam) { - snprintf(buf, sizeof buf, "%.200s/%.50s", - _PATH_MAILDIR, pw->pw_name); - child_set_env(&env, &envsize, "MAIL", buf); -@@ -1063,6 +1064,23 @@ do_setup_env(struct ssh *ssh, Session *s, const char * +- snprintf(buf, sizeof buf, "%.200s/%.50s", +- _PATH_MAILDIR, pw->pw_name); +- child_set_env(&env, &envsize, "MAIL", buf); +- } +- + /* Normal systems set SHELL by default. */ + child_set_env(&env, &envsize, "SHELL", shell); - if (getenv("TZ")) - child_set_env(&env, &envsize, "TZ", getenv("TZ")); -+#ifdef HAVE_LOGIN_CAP -+ /* Load environment from /etc/login.conf setenv directives. */ -+ { -+ extern char **environ; -+ char **senv, **var; -+ -+ senv = environ; -+ environ = xmalloc(sizeof(char *)); -+ *environ = NULL; -+ (void) setusercontext(lc, pw, pw->pw_uid, LOGIN_SETENV); -+ copy_environment_denylist(environ, &env, &envsize, NULL); -+ for (var = environ; *var != NULL; ++var) -+ free(*var); -+ free(environ); -+ environ = senv; -+ } -+#endif +- if (getenv("TZ")) +- child_set_env(&env, &envsize, "TZ", getenv("TZ")); if (s->term) child_set_env(&env, &envsize, "TERM", s->term); if (s->display) -@@ -1281,7 +1299,7 @@ do_nologin(struct passwd *pw) +@@ -1225,7 +1242,8 @@ do_nologin(struct passwd *pw) + do_nologin(struct passwd *pw) + { + FILE *f = NULL; +- char buf[1024], *nl, *def_nl = _PATH_NOLOGIN; ++ const char *nl; ++ char buf[1024], *def_nl = _PATH_NOLOGIN; + struct stat sb; + #ifdef HAVE_LOGIN_CAP - if (login_getcapbool(lc, "ignorenologin", 0) || pw->pw_uid == 0) - return; -- nl = login_getcapstr(lc, "nologin", def_nl, def_nl); -+ nl = (char*)login_getcapstr(lc, "nologin", def_nl, def_nl); - #else - if (pw->pw_uid == 0) - return; -@@ -1365,7 +1383,7 @@ do_setusercontext(struct passwd *pw) +@@ -1315,7 +1333,7 @@ do_setusercontext(struct passwd *pw) if (platform_privileged_uidswap()) { #ifdef HAVE_LOGIN_CAP if (setusercontext(lc, pw, pw->pw_uid,