PAM_LISTFILE(8)

๐Ÿ’– pam_listfile โ€” the Linux-PAM manual, but make it cute ๐Ÿ’–

okay bestie, gather round, because this one is a banger. it's pam_listfile from the Linux-PAM Manual (that's the PAM_LISTFILE(8) section of the manual, section 8, admin stuff, you know the vibe) and it is genuinely one of the most useful little gremlins in the whole PAM family. let's go ๐Ÿซถ


โœจ NAME โœจ

pam_listfile โ€” deny or allow services based on an arbitrary file. that's it. that's the whole job. she reads a file, she makes a decision, she moves on. queen behavior ๐Ÿ‘‘


โœจ SYNOPSIS โœจ

pam_listfile.so item=[tty|user|rhost|ruser|group|shell]
                sense=[allow|deny] file=/path/filename
                onerr=[succeed|fail] [apply=[user|@group]] [quiet]

look at her. look at that argument list. so structured. so slay ๐Ÿ’…


โœจ DESCRIPTION โœจ

so like, pam_listfile is a PAM module that gives you a way to deny or allow services based on an arbitrary file. it's giving "i have a list and i will be consulting it" energy ๐Ÿ“‹

here's how she works, bestie. the module grabs the item of the type you specified โ€” and the types are:

  • user specifies the username, which is PAM_USER
  • tty specifies the name of the terminal (if any) over which the request has been made, which is PAM_TTY
  • rhost specifies the name of the remote host (if any) from which the request was made, which is PAM_RHOST
  • ruser specifies the name of the remote user (if available) who made the request, which is PAM_RUSER

then she goes looking for an instance of that item inside file=filename. and filename? it contains one line per item listed. one. line. per. item. we do not do chaos in this house ๐ŸŒธ

if the item is found, then:

  • if sense=allow, PAM_SUCCESS is returned, causing the authorization request to succeed โœจ
  • else if sense=deny, PAM_AUTH_ERR is returned, causing the authorization request to fail ๐Ÿ’€

and if an error is encountered โ€” like, for instance, if filename does not exist, or a poorly-constructed argument shows up and ruins the whole mood โ€” then:

  • if onerr=succeed, PAM_SUCCESS is returned
  • otherwise if onerr=fail, PAM_AUTH_ERR or PAM_SERVICE_ERR (as appropriate) will be returned

there's also an extra argument, apply=, which can be used to restrict the application of all of the above to a specific user (apply=username) or a given group (apply=@groupname). this added restriction is only meaningful when used with the tty, rhost and shell items. like, it literally does nothing useful otherwise, so don't be weird about it ๐Ÿ™ˆ

besides that last one (apply=, our special little exception), all arguments should be specified. do NOT count on any default behavior. there is no default behavior to count on. she will not save you. specify your arguments, periodt ๐ŸŽ€

and one more thing: no credentials are awarded by this module. none. zero. she is not that kind of module.


โœจ OPTIONS โœจ

  • item=[tty|user|rhost|ruser|group|shell] โ€” what is listed in the file and should be checked for. this is the "what are we even looking at" option ๐Ÿง
  • sense=[allow|deny] โ€” the action to take if the item is found in the file. and if the item is NOT found in the file? then the opposite action is requested. flip it and reverse it ๐Ÿ”„
  • file=/path/filename โ€” the file containing one item per line. the file needs to be a plain file and not world writable. this is not a suggestion bestie, this is the vibe check and the file must pass it ๐Ÿ”’
  • onerr=[succeed|fail] โ€” what to do if something weird happens, like being unable to open the file. we love a graceful fallback ๐Ÿ˜Œ
  • apply=[user|@group] โ€” restrict the user class for which the restriction applies. note that with item=[user|ruser|group] this does not make sense, but for item=[tty|rhost|shell] it has a meaning. iykyk ๐Ÿฆ‹
  • quiet โ€” do not treat service refusals or missing list files as errors that need to be logged. she's just gonna be chill about it ๐Ÿคซ

โœจ MODULE TYPES PROVIDED โœจ

All module types (auth, account, password and session) are provided. every single one. she does it all. main character energy, no cap ๐Ÿ‘‘


โœจ RETURN VALUES โœจ

here's the receipts, bestie ๐Ÿ’–

  • PAM_AUTH_ERR โ€” authentication failure.
  • PAM_BUF_ERR โ€” memory buffer error.
  • PAM_IGNORE โ€” the rule does not apply to the apply option.
  • PAM_SERVICE_ERR โ€” error in service module.
  • PAM_SUCCESS โ€” success. our beloved. our girl. โœจ

โœจ EXAMPLES โœจ

okay this is the fun part, let's get practical ๐ŸŽ€

classic ftpusers vibes

the classic 'ftpusers' authentication can be implemented with this entry in /etc/pam.d/ftpd:

#
# deny ftp-access to users listed in the /etc/ftpusers file
#
auth    required       pam_listfile.so \
        onerr=succeed item=user sense=deny file=/etc/ftpusers

note: users listed in the /etc/ftpusers file are (counterintuitively) not allowed access to the ftp service. yes, the file is named "ftpusers" and yes, being in it means you get denied. it's giving reverse psychology, it's giving chaos, but it is what it is ๐Ÿ˜ญ

login allowlist

to allow login access only for certain users, you can use a /etc/pam.d/login entry like this:

#
# permit login to users listed in /etc/loginusers
#
auth    required       pam_listfile.so \
        onerr=fail item=user sense=allow file=/etc/loginusers

for this example to work, all users who are allowed to use the login service should be listed in the file /etc/loginusers.

โš ๏ธ unless you are explicitly trying to lock out root, make sure that when you do this, you leave a way for root to log in โ€” either by listing root in /etc/loginusers, or by listing a user who is able to su to the root account. do not lock yourself out of your own machine bestie, i am begging you ๐Ÿ™

โœจ SEE ALSO โœจ

pam.conf(5), pam.d(5), pam(8) โ€” go read those too, they're part of the lore ๐Ÿ“š


โœจ AUTHOR โœจ

pam_listfile was written by Michael K. Johnson <johnsonm@redhat.com> and Elliot Lee <sopwith@cuc.edu>. legends, honestly. thank you for your service ๐Ÿซก๐Ÿ’–


and that's the whole page!! ๐ŸŒˆ this was the Linux-PAM Manual, dated 09/27/2026, PAM_LISTFILE(8), and honestly? she ate. now go specify all your arguments and stop counting on defaults. mwah ๐Ÿ’…โœจ๐ŸŽ€

๐Ÿ“ฆ where this page comes from