Set a Login Umask with pam_umask Without Locking Out PAM
You will add pam_umask to a PAM session stack, make newly created files start with a chosen default mask, and verify the result in a fresh login session. Allow about fifteen minutes, plus time to open a second login before testing a change. You need root access to edit PAM configuration and an account that can start a new session.
The route
Jump straight to the step you need, or tick off Done means at the end.
A umask removes permission bits from newly created files and directories. It does not change existing objects, and it is not an access-control policy for an already running process. The examples use the installed libpam-modules:amd64 version 1.5.3-5ubuntu5.7.
1. Check the installed module and current defaults
These are ordinary, read-only checks. The module is a shared PAM object, not a command that you run directly:
$ dpkg-query -W -f='${Package} ${Version}\n' libpam-modules:amd64
libpam-modules:amd64 1.5.3-5ubuntu5.7
$ ls -l /lib/x86_64-linux-gnu/security/pam_umask.so
-rw-r--r-- 1 root root ... /lib/x86_64-linux-gnu/security/pam_umask.so
$ grep -E '^(UMASK|USERGROUPS_ENAB)[[:space:]]' /etc/login.defs
UMASK 022
USERGROUPS_ENAB yes
Your library path, package revision and whitespace can differ. If the last command prints nothing, that setting is absent, not automatically set to the values shown above. Also check whether the optional file exists:
$ test -f /etc/default/login && grep '^UMASK=' /etc/default/login || echo '/etc/default/login has no UMASK entry'
/etc/default/login has no UMASK entry
Checkpoint
Record the service whose PAM configuration you intend to change. The module only provides the session type, so adding it to an unrelated account or password stack will not set a login environment.
2. Choose the source of the mask
The module looks for a value in this order: a umask= entry in the user's GECOS field, a umask= module argument, UMASK in /etc/login.defs, then UMASK= in /etc/default/login. The first applicable value wins. Do not put a user-specific value in GECOS unless you have a deliberate account-management reason to do so: changing that field affects identity data used by other tools.
For a single policy that is easy to review, use an explicit module argument such as umask=0027. The value is octal and is limited to 0777. A mask of 0027 normally leaves owner access intact, removes group write access, and removes all access for other users. The permissions requested by the creating program still matter; a umask can remove bits, not add them.
The usergroups behaviour is a common source of surprises. When the user is not root and their username matches their primary group name, it can change the group mask bits to match the owner bits. With /etc/login.defs set to USERGROUPS_ENAB yes, the installed module enables that behaviour by default when no more specific setting has supplied the mask. For a predictable explicit policy, pass nousergroups with the mask. Use usergroups only when that group-sharing behaviour is wanted.
3. Back up the PAM file before editing it
Warning
A malformed PAM file can prevent logins. Keep an existing root shell, console, or out-of-band session open while testing. Do not close your only working administrative session.
Replace login with the PAM service used by the login path you are configuring. This example protects the file before editing:
# cp -p /etc/pam.d/login /etc/pam.d/login.before-pam-umask
# sudoedit /etc/pam.d/login
Use the editor opened by sudoedit and add this line in the session section:
session optional pam_umask.so umask=0027 nousergroups
The manual's example uses session optional. Keep the control flag appropriate for the service's existing policy. Do not replace other session lines, and do not add an auth, account or password line for this module. If your distribution manages the file from a PAM profile, make the equivalent change through that profile so a later update does not silently remove it.
Checkpoint
Inspect the saved file and the edited stack before opening a new session:
$ grep -n 'pam_umask' /etc/pam.d/login
12:session optional pam_umask.so umask=0027 nousergroups
$ sudo sed -n '1,80p' /etc/pam.d/login
The useful checks are the matching line and the surrounding session stack. Reading the file with sudo may be necessary because PAM configuration is normally root-readable only. If the edit is not intended for your service, stop and restore the backup before testing.
4. Test in a fresh session
Start a new login through the service you edited. An existing shell keeps its old process umask, so checking it in the same terminal can give a false negative. In the new session, run:
$ umask
0027
$ umask -S
u=rwx,g=rx,o=
Formatting for umask -S can vary slightly by shell, but the numeric value should be 0027. Create a temporary object to check the practical effect without touching an application file:
$ testdir=$(mktemp -d)
$ (umask; touch "$testdir/file"; mkdir "$testdir/dir"; stat -c '%a %n' "$testdir/file" "$testdir/dir")
0027
640 /tmp/tmp.XXXXXX/file
750 /tmp/tmp.XXXXXX/dir
$ rm -rf "$testdir"
The temporary directory name is generated by mktemp; its random suffix will differ on each run. The final command removes only this test tree. Do not substitute a real application path. If the test prints a different mask, check that you opened a new session, that the selected service includes the edited stack, and that no later shell startup file runs umask again.
5. Understand overrides and related GECOS fields
If a user has a GECOS field containing comma-separated entries such as umask=0077, that user-specific value takes precedence over the module argument. The same field can contain pri= and ulimit= entries; pam_umask recognises those too, but this guide does not use them. Inspect a user's field without changing it:
$ getent passwd LOGIN_NAME | cut -d: -f1,5
LOGIN_NAME:Full Name,Room,Work phone
Replace LOGIN_NAME with an actual account name. An empty or ordinary GECOS field means there is no user-specific umask entry. Avoid editing it as a quick fix, because the change is account data rather than a local session-stack setting.
6. Roll back safely if the session fails
Do not repeatedly guess at PAM syntax from a locked-out terminal. From the root shell or recovery path you kept open, restore the exact backup made before the edit:
# cp -p /etc/pam.d/login.before-pam-umask /etc/pam.d/login
# grep -n 'pam_umask' /etc/pam.d/login || echo 'pam_umask line removed'
Use the matching PAM service file if you changed something other than login. The module does not need a daemon restart, but existing sessions do not retroactively acquire the new mask. After restoring the file, start a fresh session and confirm that the service is usable before removing the backup. Removing it is optional and irreversible, so retain it until the change has been accepted.
Done means
- The installed
pam_umask.soand package version were checked. - The module is present once in the intended PAM
sessionstack with an explicitly chosen octal mask. - A fresh session reports the expected value from
umask. - A temporary file and directory show the expected resulting modes.
- You know whether GECOS or
USERGROUPS_ENABcan override the setting. - The pre-edit PAM file remains available until the change is proven safe.