PAM_AFS_SESSION(5)

PAM_AFS_SESSION πŸ’– (that's the pam-afs-session manual, section 5, bestie)

✨ NAME ✨

pam_afs_session β€” the AFS PAG and token PAM module πŸŽ€


🌸 SYNOPSIS 🌸

auth          optional        pam_afs_session.so
session       required        pam_afs_session.so

πŸ¦‹ DESCRIPTION πŸ¦‹

Okay so. The AFS session service module for PAM β€” usually living its best life at /lib/security/pam_afs_session.so β€” sets up brand new AFS sessions and grabs AFS tokens the moment a new session gets opened for a user. It's a shared object that the PAM subsystem dynamically loads whenever it needs it, based on your system's PAM config. Periodt.

And what even is PAM, you ask? Bestie, PAM is the whole plug-in system where external authentication and session-management modules get slotted in, so that every single application doesn't have to figure out the best way to check user authentication or spin up a user session on that system all by itself. Iconic delegation, honestly. For the deets on configuring PAM on your machine, go read the PAM man page β€” often pam(7). πŸ“–

This module gives you pam_setcred, pam_open_session, and pam_close_session implementations for AFS. And because pam_setcred belongs to the auth PAM group, it also ships a dummy pam_authenticate that always succeeds β€” because otherwise it literally cannot provide a pam_setcred. It's giving "I'm here for one job but the paperwork said otherwise". 😭

MAJOR WARNING, NO CAP: make sure this module is NEVER listed as "sufficient" or as the only "required" module in the auth group. Do that and you might genuinely let users log on with no password at all. πŸ’€ There unfortunately isn't a way to work around this and still provide pam_setcred without running afoul of a bug in (at least) Linux PAM 0.99.7.1 and probably earlier β€” one that causes authentication to fail when the final module in the auth group returns PAM_IGNORE and "[default=done]" was given as the action. So yeah. Don't do it. 🫢

Here's what this module actually does, action by action:

🌟 pam_open_session

When a new session is opened, this module first checks whether AFS is even running on the system. If it's not? It logs a message and exits successfully β€” no drama. ✨

If AFS is running, it places the user's session into a new PAG (that's a Process Authentication Group, often implemented as supplemental groups, which keeps user tokens limited to only the processes inside that PAG). Then it tries to obtain tokens β€” either directly, if it was built with the Heimdal libkafs library and Kerberos support, or by running an external aklog program. If PAG creation fails, the module fails. If obtaining tokens fails, it logs a warning but still returns success. Soft launch of a failure, I guess. πŸ™ˆ

The module will only attempt to obtain tokens if the environment variable KRB5CCNAME is set in the environment β€” unless you've configured it otherwise (peep the always_aklog option). But it will always create a new PAG, every single time. That part is non-negotiable, bestie. πŸ’…

🌟 pam_close_session

If and only if pam_open_session successfully obtained AFS tokens, and AFS is still running on the system, then pam_close_session deletes the tokens in the current PAG β€” equivalent to running unlog. Want your tokens to stick around after the session closes? Set the retain_after_close option. πŸŽ€

🌟 pam_setcred

  • Call it with the PAM_ESTABLISH_CRED flag? It does the exact same thing as if pam_open_session was called. ✨
  • Call it with the PAM_DELETE_CRED flag? It does the exact same thing as if pam_close_session was called. πŸ¦‹
  • Call it with the PAM_REINITIALIZE_CRED flag or the PAM_REFRESH_CRED flag? It will not create a new PAG β€” it'll only attempt to get new tokens (and it still skips that entirely unless KRB5CCNAME is set in the environment or always_aklog is set). 🌸

This module is primarily intended to be used alongside a Kerberos authentication module. It does not do any user authentication itself β€” it cannot, for instance, be used to authenticate users to a kaserver. Nope, not its lane. 🚫

While it's designed to work with an aklog that uses Kerberos ticket caches to obtain tokens, it can be used with any aklog implementation (though always_aklog may have to be set if no Kerberos ticket cache will be present). Versatile queen. πŸ‘‘

And finally: this module performs no authorization checks and does not hook into password changes. It only implements the session functions and pam_setcred. That's it. That's the whole vibe. πŸ’œ


to be continued… part 2 is coming, don't go anywhere bestie 🫢

πŸ’… CONFIGURATION πŸ’…

okay bestie, this is the part where you get to customize the whole vibe ✨. The AFS session PAM module supports the following config options, and you can set them either in the PAM configuration as arguments listed after pam_afs_session.so, or over in the system krb5.conf.

Some of them take arguments β€” when that's the case, the argument goes after =. The rest are just boolean options (on/off energy, no value needed). To set a boolean in the PAM configuration, literally just write the option's name in the arguments. To set one that does take an argument, follow the option name with an equal sign (=) and the value, with no separating whitespace. Also important: whitespace in option arguments is not supported in the PAM configuration files of most PAM implementations, so don't try it πŸ™ˆ.

To set an option for the PAM module in the system krb5.conf file, put that option in the [appdefaults] section. The AFS session PAM module will look for options either at the top level of the [appdefaults] section or in a subsection named pam-afs-session (currently, realm-specific configuration is not checked). For example, this little fragment of a krb5.conf file would set aklog_homedir to true and minimum_uid to 100:

[appdefaults]
    aklog_homedir = true
    pam-afs-session = {
        minimum_uid = 100
    }

There's no difference to the PAM module whether options are specified at the top level or in a pam-afs-session section; the pam-afs-session section is supported in case there are options that should be set for the PAM module but not for other applications. For more info on the syntax of krb5.conf, see krb5.conf(5).

If the same option is set in krb5.conf and in the PAM configuration, the latter takes precedent πŸ‘‘. Note, however, that due to the configuration syntax, there's no way to turn off a boolean option in the PAM configuration that was turned on in krb5.conf. That's just how it is, bestie, no cap.


  • afs_cells=cell[,cell...] β€” get tokens for the cells you list here instead of the default local cell. If you list more than one cell, it'll try to obtain tokens for each one 🎟️. If you specify this in krb5.conf, the cells can be separated by any combination of spaces and commas; if you specify it in the PAM configuration, they must be separated by commas.

If the AFS session PAM module is running an external program, this option gets implemented by passing a -c flag with the cell as its argument for each listed cell to that program. If aklog_homedir is also set, the -c flags and the -p flag will all be passed to the external program.

  • aklog_homedir β€” try to obtain the tokens you need to access the user's home directory 🏠. If the libkafs token-obtaining API is used, setting this will cause the AFS session PAM module to pass the user's home directory into that API and request that the appropriate tokens be obtained. If running an external aklog program, aklog will be called with -p home-directory where home-directory is the home directory of the local user for which the session is being opened or refreshed. This generally will tell aklog to check that path, find all AFS cells involved in access to that path, and attempt to obtain tokens for each one. Note that this means that if the user's home directory is not in AFS, no tokens will be obtained 😭.

In either case, the user's home directory is obtained via getpwnam() based on the username PAM says we are authenticating.

  • always_aklog β€” normally, the AFS session PAM module only tries to obtain tokens if KRB5CCNAME is set in the PAM environment. If this option is set, it will always attempt to obtain tokens. This is only useful if it is configured to run an external aklog program.

This can be used if your environment doesn't correctly set KRB5CCNAME in the environment for some reason, or if your aklog doesn't rely on a Kerberos ticket cache to obtain tokens (or can find the cache on its own via some other means). Very "I'll handle it myself" energy πŸ’….

  • debug β€” if this option is set, additional trace information will be logged to syslog with priority LOG_DEBUG πŸ›.
  • ignore_root β€” if this option is set, the AFS session PAM module won't take any action (and will exit successfully) if the account for which the session is being established is named "root".
  • kdestroy β€” if this option is set and the AFS session PAM module was built with Kerberos support, the user's ticket cache will be destroyed after tokens are obtained successfully. If tokens are not obtained successfully, the ticket cache will be left intact. Please note that this is not properly a security feature, since the ticket cache will still be written to disk between the time the Kerberos PAM module authenticates the user and the time the AFS session PAM module is run. It can, however, be used to reduce the window during which Kerberos ticket caches are lying about if the only use one has for ticket caches is to obtain AFS tokens.
  • minimum_uid=uid β€” if this option is set, the AFS session PAM module won't take any action (and will exit successfully) if the account for which the session is being established has a UID lower than uid.
  • nopag β€” if this option is set, no PAG will be created. Be careful when using this option, since it means that the user will inherit a PAG from the process managing the login. If sshd, for instance, is started in a PAG, every user who logs in via ssh will be put in the same PAG and will share tokens if this option is used 😬.

This is the default on Mac OS X, where PAGs are not supported.

  • notokens β€” if this option is set, the AFS session PAM module will only create a PAG and not attempt to obtain tokens. Setting this option overrides all other settings related to acquiring tokens, including always_aklog. If both nopag and notokens are set, the module essentially does nothing πŸ’€.

Setting notokens also implies retain_after_close, meaning that the AFS session PAM module will also not attempt to delete tokens when the user's session ends.

  • program=path β€” the path to the aklog program to run. Setting this option tells the AFS session PAM module to always run an external program to obtain tokens and never use the libkafs interface, even if the latter is available.

You may pass options to this program by separating them with commas (or spaces or tabs in krb5.conf or if the configuration syntax of your PAM configuration allows this). For example, the setting:

program=/usr/bin/aklog,-noprdb,-524

will run "/usr/bin/aklog -noprdb -524" as the program to obtain tokens. The arguments are passed directly, not parsed by the shell 🐚.

If this option is not set, the default behavior is to call the libkafs function to obtain tokens, if available, and otherwise to use a default path to aklog determined at compile time (the first aklog found on the compiler's path by default). If no aklog could be found at compile time and libkafs isn't used, this option must be set.

  • retain_after_close β€” if this option is set, pam_close_session will do nothing (successfully) rather than deleting tokens. This will allow programs started in the user's PAG that are still running when the log out to continue to use the user's tokens until they expire ⏳. Normally, the AFS kernel module will automatically clean up tokens once every process in that PAG has terminated.

🌿 ENVIRONMENT 🌿

  • KRB5CCNAME β€” This module looks for KRB5CCNAME in the PAM environment and by default does not run aklog if it is not set.

The entire PAM environment is passed to aklog as its environment (rather than the environment of the process running the PAM functions). Fr fr, all of it. 🫢


🚨 WARNINGS 🚨

As mentioned above, this module implements a dummy pam_authenticate function so that it can provide a pam_setcred function. Never list this module as "sufficient" or as the only "required" module or you may allow users to log on without a password 😭😭😭. Like, please don't. That's the whole warning.

While spawning an external aklog program, the AFS session PAM module resets the SIGCHLD signal handler to the default handler while the program runs and then restores it afterward. This is done to avoid having aklog interfere with process handling in the calling application, but it means that there's a race condition that can cause children to be incorrectly handled if they exit while aklog is running. There is unfortunately no good solution to this other than building against Heimdal and using the libkafs interface to obtain tokens instead of an external program.

To detect whether AFS is running on the system, the AFS session PAM module temporarily sets a SIGSYS handler before attempting an AFS system call. That handler may also modify a static variable. Neither of these should ideally be done in a PAM module, but there is no other good way of checking for the non-existence of a system call that doesn't crash the application on some operating systems. The PAM module will attempt to restore the previous SIGSYS handler, if any, after the test is done, and the static variable is used in such a way that running it from multiple threads shouldn't be an issue, but be aware that the PAM module is doing this behind the back of the application and may interfere with unusual SIGSYS handlers or similar application actions πŸ‘€.


πŸ“ NOTES πŸ“

When using the libkafs interface to obtain tokens, be sure that it is configured properly for the type of AFS tokens expected at your site. As of Heimdal 0.7, the default behavior is to contact the krb524 service to translate Kerberos v5 tickets into Kerberos v4 tickets to use as tokens. AFS cells running current server software no longer need this, and if your site doesn't run the krb524 service, this may break token acquisition πŸ’”.

Sites running AFS servers that understand Kerberos-v5-derived tokens should add configuration like:

libkafs = {
    EXAMPLE.ORG = {
        afs-use-524 = no
    }
}

to the [appdefaults] section of their krb5.conf files to disable use of the krb524 service. See the Heimdal kafs(3) man page for more information ✨.


Copyright 2015 Russ Allbery <eagle@eyrie.org>

Copyright 2005, 2006, 2007, 2008, 2009, 2010, 2011 The Board of Trustees of the Leland Stanford Junior University

Copying and distribution of this file, with or without modification, are permitted in any medium without royalty provided the copyright notice and this notice are preserved. This file is offered as-is, without any warranty.


πŸ‘€ SEE ALSO πŸ‘€

aklog(1), kafs(3), pam(7), syslog(3), unlog(1)


and that's a wrap, bestie πŸŽ€ you just read the whole thing, main character energy fr. this lil masterpiece is version 2.6, dated 2015-09-19, and it lives its life as PAM_AFS_SESSION(5). go forth and configure responsibly πŸ’–βœ¨