sshd and .bashrc

Iain Morgan imorgan at nas.nasa.gov
Fri Jul 1 10:35:31 EST 2011


I don't mean to flame you, but this bash idiosyncracy has been talked to
death time and time again on this list. Please consult the archive.

On Thu, Jun 30, 2011 at 16:34:55 -0500, Mark Bartelt wrote:
> The short version:  There's a "#define USE_PIPES"
> in the middle of session.c; it would be better if
> it were in (e.g.) defines.h or some other .h file.
> (If in fact it needs to be defined at all; I'm not
> convinced that it does.)  Here's the (much) longer
> version:
> 
> I recently installed the latest OpenSSH on some of
> our servers (RHEL5, which provides the 4.3 release)
> and soon afterward we received a complaint from one
> of our users, reporting that his .bashrc file was no
> longer being sourced when he ran remote commands via
> a non-interactive single-command connection.  He was
> right.  The problem stemmed from the fact that bash
> contains the following in run_startup_files(), which
> gets called to determine which dotfiles (if any) to
> source ...
> 
>   if (interactive_shell == 0 && no_rc == 0 && login_shell == 0 &&
>       act_like_sh == 0 && command_execution_string)
>     {
> #ifdef SSH_SOURCE_BASHRC
>       run_by_ssh = (find_variable ("SSH_CLIENT") != (SHELL_VAR *)0) ||
> 		   (find_variable ("SSH2_CLIENT") != (SHELL_VAR *)0);
> #else
>       run_by_ssh = 0;
> #endif
>       /* If we were run by sshd or we think we were run by rshd, execute
> 	 ~/.bashrc if we are a top-level shell. */
>       if ((run_by_ssh || isnetconn (fileno (stdin))) && shell_level < 2)
> 
> ... and RedHat's bash is built with SSH_SOURCE_BASHRC
> not defined, so everything depends on isnetconn(); in
> fact, that seems to be bash's default, since one finds
> this in a (very old) entry in their CHANGES file:
> 
> This document details the changes between this version, bash-2.05a-release,
> and the previous version, bash-2.05a-rc1.
>  [ ... ]
> z.  Bash no longer attempts to discover if it's being run by sshd in order to
>     run the startup files.  If the SSH_SOURCE_BASHRC is uncommented in
>     config-top.h it will attempt to do so as previously, but that's commented
>     out in the distributed version.
> 
> But it turns out that bash's isnetconn() function was
> returning 0, which in turn was caused by getpeername()
> failing (errno == ENOTSOCK) when it was being used to
> get information about stdin.
> 
> And sure enough, the child process spawned by Redhat's
> sshd showed the following for standard input (reported
> by "lsof") ...
> 
> 0u     unix 0xffff81033fec2b80           10237328 socket
> 
> ... whereas the same child process spawned by the sshd
> which I'd just built had this ...
> 
> 0r     FIFO    0,6            3093574 pipe
> 
> So what was responsible for this difference?  It turns
> out that there's some code in session.c (specifically,
> in the do_exec_no_pty() function) conditionalized with ...
> 
> #ifdef USE_PIPES
>  [ ... ]
> #else
>  [ ... ]
> #endif
> 
> ... so this might lead one to believe that there would be
> something in one of the .h files that would govern which
> of those chunks of code would get used, particularly in
> light of the fact that defines.h contains ...
> 
> /*
>  * Define this to use pipes instead of socketpairs for communicating with the
>  * client program.  Socketpairs do not seem to work on all systems.
>  *
>  * configure.ac sets this for a few OS's which are known to have problems
>  * but you may need to set it yourself
>  */
> /* #define USE_PIPES 1 */
> 
> ... and the configure script creates a config.h with ...
> 
> /* Use PIPES instead of a socketpair() */
> /* #undef USE_PIPES */
> 
> ... both of which would lead one to infer that USE_PIPES
> is _not_ defined by default.  But back in session.c, more
> then four hundred lines from the beginning of the file, we
> find this ...
> 
> #define USE_PIPES
> 
> ... just before the start of the do_exec_no_pty() function!
> 
> This wasn't always there; it appeared for the first time in
> the 5.1p1 release (it's not in 5.0p1).
> 
> So first, I'm curious as to why it was felt necessary to make
> USE_PIPES the default; and secondly, even if there is a good
> reason for it to be the default, shouldn't the "#define" be
> in a .h file, so that it will be obvious what the setting is
> for people who might want to change it?
> 
> Burying it down in the middle of session.c just seems like an
> unwise decision ...
> 
> ---------------
> 
> Mark Bartelt
> Center for Advanced Computing Research
> California Institute of Technology
> Pasadena, California  91125
> 
> 626 395 2522
> 626 584 5917 fax
> 626 628 3994 e-fax
> 
> mark at cacr.caltech.edu
> 
> http://www.cacr.caltech.edu/~mark
> _______________________________________________
> openssh-unix-dev mailing list
> openssh-unix-dev at mindrot.org
> https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev

-- 
Iain Morgan


More information about the openssh-unix-dev mailing list