Home / Alt manpages / pam_localuser(8)

  • pam_localuser(8)
  • Admin command
  • linux

Use pam_localuser to Separate Local and Network Accounts

You will add a PAM rule that recognises users listed in a passwd file, then combine that result with a group check so local users or an approved administrator group can use a service. The examples use Linux-PAM from Ubuntu package libpam-modules:amd64, version 1.5.3-5ubuntu5.7, installed on the reference system.

Allow about fifteen minutes for a configuration review and a controlled test. You need root access to edit a PAM service file, and a second administrative path for recovery. This guide does not edit a live PAM file for you. PAM mistakes can lock out logins, remote access or privilege escalation.

1. Check the module and the account source

Run these read-only commands as your ordinary user:

$ dpkg-query -W -f='${Package} ${Version}\n' libpam-modules:amd64
libpam-modules 1.5.3-5ubuntu5.7
$ ls -l /lib/x86_64-linux-gnu/security/pam_localuser.so
-rw-r--r-- 1 root root ... /lib/x86_64-linux-gnu/security/pam_localuser.so

The exact module path and file metadata can differ on another architecture. The module's normal account source is /etc/passwd. It asks PAM for the current user, then checks that name in the selected passwd file. It does not authenticate a password and it does not define which group a user belongs to.

Checkpoint: choose one existing local test account and one account that is not listed in /etc/passwd, if your system has both. Do not create or delete accounts just to test this module. On systems using LDAP, SSSD or another directory, do not assume that a directory user is local merely because commands such as getent passwd can resolve it.

2. Understand the PAM line before editing it

A service file under /etc/pam.d/ uses the form type control module arguments. For pam_localuser, the module line is commonly:

account sufficient pam_localuser.so

The module supplies all four PAM management types, but account is the useful choice for an access policy. With the sufficient control, a successful local-user check can finish the account stack if no earlier required module has failed. A failed sufficient check is ignored, so later modules can handle network users or deny them.

This is a policy decision, not a harmless status check. A local account that passes this line may be accepted before later account rules run. Read the whole target stack first, including included files, and check how the service's application interprets PAM results.

3. Back up the target service file

Choose the service deliberately. The manual's example uses su, so this command inspects that file without changing it:

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

Do not paste the example into every file in /etc/pam.d/. Add the rule only to the service whose access policy you are changing. Before editing, make a root-owned backup:

$ sudo cp --preserve=all /etc/pam.d/su /etc/pam.d/su.before-pam-localuser
$ sudo ls -l /etc/pam.d/su /etc/pam.d/su.before-pam-localuser

Checkpoint: confirm that both files exist and that the backup was made before the edit. The backup is your recovery path. Keep an already-open root shell or console session while testing; do not close the only route back into the machine.

4. Allow local users or the wheel group

For a service where that policy is genuinely intended, the manual gives this stack:

account sufficient pam_localuser.so
account required pam_wheel.so

The first line lets a user listed in the selected passwd file pass without reaching the wheel check. A user who is not in that file falls through to pam_wheel, which then requires membership of its configured wheel group. This is an OR policy, not a rule that makes every local user a wheel member.

Insert the lines at the correct point in the service's existing account stack. Preserve vendor comments and included rules. Use an editor with elevated privileges, for example:

$ sudoedit /etc/pam.d/su

Do not use sudo sh -c with an unquoted, generated configuration string. Do not replace the entire file with the two-line example. A malformed line or an unexpected control flag can change access for every user of that service.

5. Use a different passwd file only for a deliberate policy

The file= option changes the file checked by the module:

account sufficient pam_localuser.so file=/etc/security/service-users

The path is a module argument, not a shell command. The file must contain passwd-style account entries that the installed PAM implementation can inspect. Treat it as security-sensitive configuration: make it root-owned, restrict write access, and review who can alter it. A writable allow-list is an access-control bypass.

Verify the file and its permissions before activating the rule:

$ sudo stat -c '%U:%G %a %n' /etc/security/service-users
root:root 640 /etc/security/service-users
$ sudo sed -n '1,20p' /etc/security/service-users

The module also accepts debug, which writes diagnostic information to the system log. Use it temporarily when investigating a controlled test, then remove it. Unrecognised options are logged as errors, so spell file= exactly.

6. Test without taking away your recovery path

There is no standalone pam_localuser executable. The module runs inside a PAM-aware application. Test through the actual service, using a disposable or already-approved account and a second session. For a change to su, keep the current root or administrator shell open and test from another terminal:

$ su - TEST_LOCAL_USER -c 'id -un'
TEST_LOCAL_USER
$ su - TEST_NETWORK_USER -c 'id -un'
su: Authentication failure

The exact failure text and whether a password is requested depend on the rest of the service stack. Do not treat a successful id command as proof that every PAM path has the same policy. Test the real service, both an intended local user and an intended non-local user, and inspect the system journal if the result differs from the stack you reviewed.

If the result is wrong, stop testing and restore the backup rather than improvising another rule:

$ sudo cp --preserve=all /etc/pam.d/su.before-pam-localuser /etc/pam.d/su
$ sudo sed -n '1,220p' /etc/pam.d/su

Restoring the file undoes this example's configuration change. It does not undo unrelated edits made after the backup, so compare the file before restoring if other administrators may have changed it.

7. Know the failure boundaries

A user missing from the selected passwd file returns PAM_PERM_DENIED. An unavailable passwd file or invalid user name returns a service error. If PAM cannot obtain the user name through its conversation method, the module can return a conversation or incomplete error. These are module results; the control flag in the service file decides whether they are ignored, recorded as a failure or terminate the stack.

pam_localuser is not a replacement for pam_wheel, pam_listfile, directory authentication or password verification. It answers one narrow question: is the current name present in the configured passwd file? Use another module when the policy depends on group membership, a maintained allow-list, a directory, or credentials.

Done means

  • You confirmed the installed Linux-PAM package and module path.
  • You chose one PAM service and read its complete account stack before editing.
  • You backed up the service file and kept a separate recovery session open.
  • You used account sufficient pam_localuser.so only where the local-user policy is intended.
  • Any file= passwd file is root-owned and not writable by the accounts it protects.
  • You tested both an allowed local account and the intended non-local path, then restored the backup if the result was wrong.