Linux – where is the PATH for users set in linux, before any shell, or sudo, pam.d changes it

environment-variableslinux

I noticed that in Raspbian that if I run a command via ssh without using a shell, I get the following $PATH;

$ ssh pi@raspberrypi env | grep PATH
PATH=/usr/local/bin:/usr/bin:/bin:/usr/games

I can't find where this path is actually set.

I am assuming that neither /etc/profile or /etc/bashrc are sourced, because its not a login and its not an interactive shell. It looks like it would probably visit bashrc, but that it wouldn't get very far;

# cat /etc/bash.bashrc 
# System-wide .bashrc file for interactive bash(1) shells.

# If not running interactively, don't do anything
[ -z "$PS1" ] && return

pam
However it looks like the session would be processed through pam, and the /etc/pam.d/sshd suggests that /etc/environment, /etc/security/pam_env.conf and /etc/default/locale are used to set environment variables;

# Read environment variables from /etc/environment and
# /etc/security/pam_env.conf.
session    required     pam_env.so # [1]
# In Debian 4.0 (etch), locale-related environment variables were moved to
# /etc/default/locale, so read that as well.
session    required     pam_env.so user_readenv=1 envfile=/etc/default/locale

However on this machine, none of those files contain any references to setting the path. e.g.

# cat /etc/default/locale
#  File generated by update-locale
LANG=en_GB.UTF-8

# cat /etc/environment
root@raspberrypi:~# 

# cat /etc/security/pam_env.conf | grep "^[^#;]"
root@raspberrypi:~# 

login.defs
The only place I could find a path set similar to

PATH=/usr/local/bin:/usr/bin:/bin:/usr/games

was in the /etc/login.defs file;

login.defs:ENV_PATH        PATH=/usr/local/sbin:/usr/local/bin: \
/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/games:/usr/games

It looks like that latter path has the elements in the right order, but with the sbin components stripped out. However the docs for login.defs suggest this file is mostly deprecated;

Much of the functionality that used to be provided by the shadow
password suite is now handled by PAM. Thus, /etc/login.defs is no
longer used by passwd(1), or less used by login(1), and su(1). Please
refer to the corresponding PAM configuration files instead.

/home/pi/.bashrc
The pi users was created with some skeleton files, but none of them would appear to be read for a non-interactive, non-login shell;

# cat /home/pi/.bashrc 
# ~/.bashrc: executed by bash(1) for non-login shells.

# If not running interactively, don't do anything
case $- in
    *i*) ;;
      *) return;;
esac

/home/pi/.profile

# cat /home/pi/.profile 
# ~/.profile: executed by the command interpreter for login shells.
# This file is not read by bash(1), if ~/.bash_profile or ~/.bash_login

Is that original $PATH hard coded into a binary somewhere, or am I missing something?

Best Answer

It's hard-coded in the sshd binary.

$ strings /usr/sbin/sshd |grep /usr/local/bin
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/bin/X11
/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games

In the OpenSSH portable code, that's _PATH_STDPATH which defaults to /usr/bin:/bin:/usr/sbin:/sbin for both root and non-root. The Debian build rules set this to /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin for root, /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games for non-root on Ubuntu, /usr/local/bin:/usr/bin:/bin on installation live media (udeb), and /usr/local/bin:/usr/bin:/bin:/usr/games for non-root otherwise.

Related Question