Home / Alt manpages / pam_mkhomedir(8)

  • pam_mkhomedir(8)
  • Admin command
  • linux

Create Missing Network User Home Directories with PAM

You will configure pam_mkhomedir so a user who exists in a central identity source receives a local home directory when a PAM session starts. The module copies the selected skeleton files, applies a predictable directory mode, and leaves the directory in place after logout. These examples use Linux-PAM from Ubuntu package libpam-modules version 1.5.3-5ubuntu5.7.

Allow about 15 minutes, plus one test login. You need root access, a readable skeleton directory, and a PAM service that your users actually use, such as SSH or a display manager. This changes authentication-session configuration, so keep an existing root shell or console session open while testing.

Safety warning

A malformed PAM file can prevent logins. Back up the service file before editing it, change one service at a time, and do not close your working administrative session until a new login has succeeded.

1. Confirm the module and choose the PAM service

Check that the package and module are installed:

$ dpkg-query -W -f='\${Package} \${Version}\n' libpam-modules:amd64
libpam-modules:amd64 1.5.3-5ubuntu5.7
$ test -r /usr/lib/x86_64-linux-gnu/security/pam_mkhomedir.so && echo 'module present'
module present

The PAM service file controls when the module runs. For SSH, that is normally /etc/pam.d/sshd; for a text console it may be /etc/pam.d/login. Inspect the file you intend to change and confirm that it has a session section:

$ sudo sed -n '1,220p' /etc/pam.d/sshd

Replace sshd in the command with the service used by your central-login path. Do not add this line to an unrelated service and assume it will affect every login.

2. Inspect the skeleton and permission defaults

Files in /etc/skel are copied into a newly created home directory. Review them before enabling the module, because a skeleton can contain shell startup files and other user-visible defaults:

$ sudo find /etc/skel -maxdepth 2 -printf '%M %u:%g %p\n'
$ grep -E '^(HOME_MODE|UMASK)[[:space:]]' /etc/login.defs

On this machine, HOME_MODE 0750 and UMASK 022 are present. Without an explicit umask= option, this installed module uses HOME_MODE when it is available. If it is absent, it computes a mode from UMASK; if neither setting exists, the documented fallback is 0755.

This is a directory permission decision, not just a formatting option. A mode such as 0750 prevents unrelated users from reading the home directory, but may not suit every shared-group arrangement. Decide the policy before editing PAM.

3. Back up the service file

Run this as root, substituting the service you selected:

$ sudo cp --preserve=mode,ownership,timestamps /etc/pam.d/sshd /etc/pam.d/sshd.before-pam_mkhomedir
$ sudo ls -l /etc/pam.d/sshd /etc/pam.d/sshd.before-pam_mkhomedir

The backup gives you a direct recovery path. If a later login test fails, restore it from the still-open administrative session with:

$ sudo cp --preserve=mode,ownership,timestamps /etc/pam.d/sshd.before-pam_mkhomedir /etc/pam.d/sshd

4. Add the session rule

Edit the chosen PAM file as root and add one line in its existing session section:

session required pam_mkhomedir.so skel=/etc/skel/ umask=0022

The session module type is the only type provided by pam_mkhomedir. The required control means that failure is reported as a PAM failure, although PAM may still run later session modules before returning. The example makes the creation mask explicit and uses the normal skeleton directory. If you want the service to follow HOME_MODE and UMASK instead, omit umask=0022:

session required pam_mkhomedir.so skel=/etc/skel/

Use an alternative skeleton only when you have deliberately created and reviewed it, for example skel=/srv/login-skel/. The path must be readable by the session process. Do not put passwords, private keys or machine-specific secrets in any skeleton directory.

Checkpoint

Inspect the finished session section before testing. Look for a single correctly spelt pam_mkhomedir.so line, the intended control flag, and a skeleton path that exists.

5. Test with a user whose home is missing

Start a new login through the service you changed using a real centrally managed account whose home directory does not already exist. Do not delete an existing home directory just to force a test: that would destroy user data. If you have a disposable test account, confirm its home path first:

$ getent passwd EXAMPLE_USER
EXAMPLE_USER:x:20001:20001:Example User:/home/EXAMPLE_USER:/bin/bash
$ sudo test ! -e /home/EXAMPLE_USER && echo 'home is absent'
home is absent

After the new session opens, check the result from the retained administrative session:

$ sudo stat -c '%A %a %U:%G %n' /home/EXAMPLE_USER
drwxr-x--- 750 EXAMPLE_USER:EXAMPLE_USER /home/EXAMPLE_USER
$ sudo find /home/EXAMPLE_USER -maxdepth 1 -mindepth 1 -printf '%f\n' | sort
.bash_logout
.bashrc
.profile

The exact skeleton file list depends on your host. The useful checks are that the directory owner and group match the account, its mode matches your policy, and expected skeleton files were copied. The module does not remove the directory when the user logs out.

6. Diagnose a failed session

If the login fails with a PAM error, restore the backup first, then investigate. A PAM_PERM_DENIED result means the module could not create the home directory or read the skeleton. Check the parent directory, the selected skeleton, and the account's home path without changing them:

$ getent passwd EXAMPLE_USER
$ sudo namei -l /home/EXAMPLE_USER
$ sudo test -r /etc/skel/.profile && echo 'skeleton readable'
$ sudo journalctl -b --no-pager | grep -iE 'pam_mkhomedir|pam|EXAMPLE_USER' | tail -n 40

PAM_USER_UNKNOWN means the underlying authentication stack does not know the user at the point this session module runs. Fix identity lookup and account ordering rather than creating a directory by hand. A home that already exists is not recreated; check its ownership and permissions separately.

The optional silent argument suppresses informative messages. The optional debug argument sends diagnostic information to syslog. Use debug temporarily when your logging policy permits it, then remove it after diagnosis. It does not repair permissions or create a home outside the PAM session.

Done means

  • The installed pam_mkhomedir.so module and package version were confirmed.
  • The correct PAM service has one reviewed session rule.
  • The skeleton directory and home-directory mode match your access policy.
  • A fresh test login created the expected home with the right owner, group and permissions.
  • The original service backup remains available until the change has been observed in normal use.