Home / Alt manpages / pam_getenv(8)

  • pam_getenv(8)
  • Admin command
  • linux

Read Debian Environment Values Safely with pam_getenv

You will use pam_getenv to read one named value from the system environment configuration, check the result and distinguish a missing variable from a command failure. Allow about ten minutes. You need a Debian or Ubuntu system with the libpam-runtime package installed; the examples only read configuration and do not change a service or account.

1. Check the installed command and version

Start by confirming which executable will run. On this machine, pam_getenv is supplied by libpam-runtime version 1.5.3-5ubuntu5.7. The exact output on your host can differ, and the package version matters because this is a small Perl utility whose behaviour can change with the distribution package.

$ command -v pam_getenv
/usr/sbin/pam_getenv
$ dpkg-query -W -f='${Package} ${Version}\n' libpam-runtime
libpam-runtime 1.5.3-5ubuntu5.7

If command -v finds nothing, stop here and install the package through your normal distribution process. Do not copy a script into /usr/sbin as a workaround. Package ownership and future upgrades are part of the command's safety boundary.

Checkpoint

You have a package-managed pam_getenv, and you know which version you are testing.

2. Read a known variable

The required argument is the environment variable name, not a shell assignment and not a path. The command prints the value followed by a newline. On this host, PATH is defined in /etc/environment, so it is a useful read-only test:

$ pam_getenv PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin

Use a quoted name when it comes from another command or a script, even though ordinary shell variable names do not contain spaces:

$ ENV_NAME='PATH'
$ pam_getenv "$ENV_NAME"
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin

Reading the value is normally unprivileged. sudo is not needed for the installed files on a standard system, and using it can make troubleshooting less clear by changing the execution context.

3. Compare the result with the source file

The manual describes the command as reading /etc/environment. Inspect that file when you need to establish what is configured rather than what a shell currently inherited:

$ sed -n '/^[[:space:]]*#/!{/^[[:space:]]*$/!p;}' /etc/environment
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin"

Do not use printenv PATH as a substitute for this check. printenv reports the current process environment, which can contain shell or service-specific changes. pam_getenv performs its own lookup from the PAM environment configuration files.

The installed 1.5.3-5ubuntu5.7 script also reads /etc/security/pam_env.conf before reading /etc/environment. Values found later in /etc/environment replace the same variable name, so the two files are not independent namespaces. Treat the installed script and package version as the authority when a host has non-empty pam_env.conf rules.

4. Understand expansion and quoting

The utility attempts to expand environment references in values. In the installed script, references written as ${NAME} are looked up in the process environment, and an unset referenced name becomes an empty string. That is not the same as asking the shell to expand the whole configuration file before pam_getenv runs.

Values in /etc/environment can be quoted. The installed parser removes a matching leading quote and a trailing quote, following the parsing rules used by pam_env. Keep the configuration syntax simple and verify the final value with the command:

$ pam_getenv LANG
en_GB.UTF-8
$ printf 'value length: %s\n' "$(pam_getenv LANG | wc -c)"
value length: 12

The exact locale value is host-specific. The useful verification is that the returned value is the one you expect, not that it matches this example.

A value containing a PAM item reference, such as an unescaped @{PAM_USER} form, is rejected by the installed implementation with Cannot handle PAM items. Do not treat that diagnostic as proof that the referenced PAM item is empty. It means this standalone utility cannot expand that type of reference.

5. Check missing names without changing anything

Ask for a deliberately unlikely name to see how this version behaves when a variable is absent:

$ pam_getenv PAM_GETENV_NAME_THAT_IS_NOT_SET
$ printf 'exit status: %s\n' "$?"
exit status: 0

There is no output, but the installed script still exits with status 0. This is the most distracting default: a successful process status does not prove that a value was found. In a script, capture the output and test whether it is non-empty if an empty value is not valid for your use case:

$ value=$(pam_getenv PAM_GETENV_NAME_THAT_IS_NOT_SET)
$ if [ -n "$value" ]; then printf '%s\n' "$value"; else printf '%s\n' 'no value returned'; fi
no value returned

An empty configured value and a missing variable produce the same empty output in this simple test. If that distinction matters, inspect the relevant configuration files and define a policy for empty values before automating around the command.

6. Treat the compatibility flags correctly

The synopsis accepts -l and -s. The manual says that -l is reserved for default locale information and -s for a system default environment, but also says that neither option currently does anything. They are compatibility flags for a possible future Debian split of the configuration sources.

$ pam_getenv -l PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
$ pam_getenv -s PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin

Do not add either flag expecting locale selection, service isolation or a different file. On this installed version, the output is unchanged. If a later package gives these options meaning, re-read that package's manual before relying on the old behaviour.

7. Diagnose failures and avoid configuration damage

No argument is an actual usage error:

$ pam_getenv
Usage: pam_getenv [-l] [-s] env_var
$ printf 'exit status: %s\n' "$?"
exit status: 255

A failure to open /etc/security/pam_env.conf is also a configuration or permissions problem, not evidence that the requested variable is absent. Check file ownership, mode and package integrity with your normal administrator tools. Reading the file can usually be done without elevation; changing it requires elevated privileges and can affect login sessions.

Warning

Do not edit /etc/environment or /etc/security/pam_env.conf just to make a test value appear. A malformed environment file can affect graphical logins, remote sessions and services that use PAM. If a change is genuinely required, save a root-owned backup first, make the smallest documented edit during a maintenance window, then start a fresh session and verify with pam_getenv. To undo it, restore the backup or remove only the line you added, then repeat the fresh-session check.

Done means

  • pam_getenv is installed from libpam-runtime, and its package version is recorded.
  • A known variable was read and compared with the relevant configuration.
  • You know that this installed version also reads /etc/security/pam_env.conf.
  • You tested missing-name handling instead of relying on exit status alone.
  • You understand that -l and -s are currently no-op compatibility flags.
  • No configuration, login session or service was changed.