Set Environment Variables Using pam_env
Why pam_env
It’s a PAM module and sets environment variables as soon as user logs in.
Bash, zsh or fish; Wayland or Xorg; no need to bother understanding their environment scopes, not as global as pam_env anyway.
Why not
- May be too global if want set environment variable in certain scope like only under shell or GUI;
- Configuration files are pure text, not any kind of shell script;
- Require root permission since version 1.4.0 (Or count on default configuration of distro).
Configuration Files#
pam_env
reads these three files below in turn:
/etc/security/pam_env.conf
: This file need to be correctly parsed (empty is fine), or the other two files won’t be parsed at all./etc/environment
: Simple[export ]KEY=VAL
syntax, no spaces escaping,#
for comments.~/.pam_environment
: User-levelpam_env.conf
, disabled by default since v1.4.0.
User-Level Configuration#
Since PAM v1.4.0, pam_env module doesn’t read user-level configuration file by default. To enable user-level config, one has to be administrator to append argument in system-level config of PAM.
Run grep pam_env.so /etc/pam.{conf,d/*}
to see all the references of pam_env module,
file results depend on distros and personal use case.
On Gentoo and Arch Linux it’s /etc/pam.d/system-login
to be altered,
go to the session required pam_env.so
line and append argument user_readenv=1
.
(Note for Arch Linux users: pambase
package of has already done the work above.)
Additionally, to custom file path instead of default ~/.pam_environment
,
append argument user_envfile=path
, in which the path
is relative to every user’s home.
The altered line may look like:
session required pam_env.so user_readenv=1 user_envfile=.config/pam_env.conf
Configuration Syntax#
VARIABLE_NAME [DEFAULT=[value]] [OVERRIDE=[value]]
For quick and simplest usage: VARIABLE_NAME DEFAULT=value
usually works like bash command export VARIABLE_NAME=value
.
Priority Mechanism#
- Override value if provided and expanded to non-empty string;
- Undefined (deleted) if literally
DEFAULT=
provided; - Default value including empty string expanded or provided with
""
.
Expanding#
For defined values:
- Use
${VARIABLE_NAME}
to expand variables; - Use
@{PAM_ITEM_NAME}
to expand PAM_ITEMs including:- PAM_USER
- PAM_USER_PROMPT
- PAM_TTY
- PAM_RUSER
- PAM_RHOST
Special variables @{HOME}
and @{SHELL}
are expanded to values for user according
to its record in user database, which is /etc/passwd
file in most cases.
Escaping#
- Use
\$
and\@
for their literal values; - Use
"value containing spaces"
to escape spaces, escaped"
not supported; - Use backslash at end of line to escape newlines
\n
; - Use
#
to start comments anywhere, escaped#
not supported.
Examples#
(These examples are from Dave Kinchlea, original author of pam_env module.)
Set the REMOTEHOST
variable for any hosts that are remote,
default to “localhost” rather than not being set at all:
REMOTEHOST DEFAULT=localhost [email protected]{PAM_RHOST}
Set the DISPLAY variable if it seems reasonable:
DISPLAY DEFAULT=${REMOTEHOST}:0.0 OVERRIDE=${DISPLAY}
Now some simple variables:
PAGER DEFAULT=less
MANPAGER DEFAULT=less
LESS DEFAULT="M q e h15 z23 b80"
NNTPSERVER DEFAULT=localhost
PATH DEFAULT=${HOME}/bin:/usr/local/bin:/bin\
:/usr/bin:/usr/local/bin/X11:/usr/bin/X11
Silly examples of escaped variables, just to show how they work:
DOLLAR DEFAULT=\$
DOLLARDOLLAR DEFAULT= OVERRIDE=\$${DOLLAR}
DOLLARPLUS DEFAULT=\${REMOTEHOST}${REMOTEHOST}
ATSIGN DEFAULT="" OVERRIDE=\@
References#
Source Code#
linux-pam/pam_env.c at v1.4.0 · linux-pam/linux-pam · GitHub
Documentation#
Linux-PAM: 6.6. pam_env - set/unset environment variables
Arch Linux: Environment variables - ArchWiki