Last update: January 28, 1998

Pluggable Authentication Modules information


Information

This is not intended as a generic PAM page. You can find info on the Linux PAM project as well as many pointers on the Linux PAM web page. It should be noted that "Linux PAM" is not really. Rather, it's PAM, but not Linux-specific. It's been ported to FreeBSD, Solaris, SunOS and HP-UX 9.0 (though the current version does *not* have defaults for FreeBSD, so it would be nice if someone would contribute some back).
As background information you may wish to read the DCE RFC on PAM

My work

As an interested party before my employers were at all interested in PAM I did several modules. All have been built under Solaris 2.6 using the Linux PAM distribution as a toolkit (it will require gmake but otherwise will be able to use your stock tools if you copy the appropriate defs file in). They are:
pam_krb4
A Kerberos 4 module which does authentication and Kerberos password changes. It takes advantage of the setcred portion of the authentication module API to only set up a credential cache if authentication and accounting checks have succeeded. It is capable of dealing with both AFS and MIT style Kerberos passwords. As it is only an authentication module and includes no encryption code itself it is believed to be exportable (Consider it a Bones module which happens to also be useable with Kerberos, if it makes you happier).
pam_afstok
An AFS token module which uses the Kerberos 4 module's resulting Kerberos ticket to fetch an AFS token for the user. Originally a session module, it is being rewritten to be an authentication module exporting only a setcred interface.
pam_afspass
An AFS password changing module which uses the AFS API for password changing. It does not rely on Kerberos 4 in any way. Currently it cannot be used on platforms which do not support either PIC static libraries (like SGIs) or linking static libraries into shared objects through use of fixups (like at least i386 and Sparc Linux, Solaris/SPARC and possibly SunOS/SPARC)
pam_afsauth
An AFS authentication module which uses the AFS API for authentication. This module is not yet available but is structured similarly to the Kerberos 4 module, while not being dependant on Kerberos code.
pam_syslog
A module which syslogs the module stub reached and then returns success (or optionally "permission denied" based on arguments passed to the module in the PAM configuration). This is primarily useful for debugging code where neither the modules nor the program are available for debugging. Calls to the syslog module can bracket other modules and be used to determine points of failure.
pam_restrict
A module which is a wrapper around a library used by CMU Computing Services to restrict access to "public" machines. It provides two features. The first is restricted access for remote logins while the console is in use. Only privileged users and the console user may log in via remote logins. The second is access control based on AFS PTS groups using a mechanism known as user permits, where PTS users and groups are listed in a user permits file to allow logins, or optionally preceded with a "-" to deny login. The "restrict" library is or will be available from the Andrew II software distribution site

Experiences with PAM and Solaris

While attempting to set up CDE on our pilot Solaris 2.6 system to use my PAM modules so that a reasonable facsimile of our standard environment could be supported while also allowing us to move toward CDE I discovered several interesting things which may be useful to other sites using PAM with Solaris 2.6. First I list the discoveries, and then the bugs I know of.
Use of symbolic binding
When linking a shared object for use as a PAM module, if linking against static libraries -Bsymbolic may be used to force needed symbols to be included in the module at link time. This is useful for modules like the AFS module, and, if being compiled without shared Kerberos libraries, the Kerberos module. It does however have some effects you may not expect. Read on.
Forcing symbols to resolve as you want them to
When first experimenting with my Kerberos module I found that it was being called, but failing even though it was getting the right input, at least when being called from passwd (after resolving other problems which I will get to in a second). It worked when called from a passwd binary I compiled from the Sample Linux PAM apps. The only difference that was obvious was theirs was linked with -lnsl, whereas mine wasn't. Bingo!
libnsl includes des code for use with the SunRPC DES authentication stuff, but this DES does not interoperate completely with the standard DES library used with Kerberos 4. Even though I was doing symbolic binding at link time in the module and linking with -ldes before -lnsl I was still getting the symbols from the executable. I fixed this by linking in a static libkrb and libdes. Merely linking static libdes is not sufficient since libkrb apparently still uses the symbols from the executable (or rather, the symbols first defined in the executable).
I'm also told the nsl library contains incompatible MD5 code, and while I have not verified it, I have no reason not to believe it. So, even when doing symbolic binding at module link time, beware of conflicts which can have unexpected consequences.
Incompatibility between early Linux PAM and Solaris PAM
While Linux PAM was implemented from the DCE RFC, Solaris PAM deviated (slightly). Specifically, two cases caused problems early on.
In one case Sun decided pam_strerror() required the PAM handle to be passed to it, while the RFC specifies the opposite. In the other case, the response structure is filled differently. A response item is returned for each message sent to the conversation function (if I recall correctly) instead of only for "prompt" messages sent. So modules written to work with Linux PAM versions 0.58 and before will need to be updated to work with either newer versions of Linux PAM or with Solaris PAM.
Incompatibility between recent Linux PAM and Solaris PAM
Linux PAM versions up to 0.61 used incompatible flags to signal things like preliminary password and new password steps while changing authentication tokens, and for signaling what portion of the setcred() API was being used (e.g. ESTABLISH, REFRESH, DESTROY). In Linux PAM 0.62 patches I contributed to fix this appeared; When compiled on a Solaris machine Linux PAM uses flags which match those used by Solaris instead of by Linux. This means that modules compiled under Solaris will never work in binary compatibility under SparcLinux, but little else.
I then discovered that while all of the error codes which exist in Linux PAM also exist on Solaris, some have different return values. A patch addressing this is expected to be in Linux PAM 0.63 and is available from me. It swaps the error codes such that when compiled on Solaris, Linux PAM uses Solaris' idea of error codes instead of its own, resulting in the same problem as above.
Alan DeKok (alan@cryptocard.com) reports that PAM_TEXT_INFO when used in conversation by a module will result in the desired text being printed, and then skipping to the next authentication mechanism (or presumably the next module for session, account or password).
Frank Cusack (fcusack@iconnet.net) reports that he has not had this problem, so it potentially has been fixed.
Source incompatibility between Linux PAM and Solaris PAM
Since Linux PAM ships with an additional library with added features and an enhanced set of macros, modules written for Linux PAM will not necessarily "just compile" for Solaris. Generally this means only that you need also build Linux PAM for Solaris for use as a toolkit. While I do not consider this a problem, you may.
Incompatibilities among PAM applications
Note that I don't say "bug" since the "right" behavior isn't defined. The util-linux login patches call the pam_sm_setcred() portion *after* the setuid happens. The Solaris login calls it before. This means you potentially need to chown things like Kerberos ticket files yourself. Be careful, though, that you're not chowning a symlink to something else in the process, if you need to do something like this in your code!
Also, dtlogin, but not Solaris login, seems to get unhappy if you pam_set_item(PAM_USER); It expects this data to be filled in by pam_get_user() only, and not for the module to explicitly try to set it. This is fine, it just means you need to make your module work in this manner.
Bugs with Sun's PAM and PAM-aware tools
dtlogin is not linked against libpam
This means modules may need to link against libpam explicitly if they call things like pam_get_item. This can be greatly annoying.
dtlogin bugs
dtlogin has problems where login is not completed before the pam "session" is closed, causing an invalid pam handle to be passed to everything after the accounting step. It also fails to export environment created with pam_putenv(). This is currently in SunSolve as bug 4091713. These appear to be fixed by patch 105703-03
CDE screenlock does not use PAM at all
Self explanatory. This is bug 1257622. It's fixed in whatever the latest patch is.
Telnet uses PAM, and wants the pam_unix module regardless of what you tell it.
Alan DeKok reports:
For some unknown reason, Solaris telnetd is linked against PAM. It's also seriously broken, in that it *always* uses unix authentication, even if you ask it not to. In order to successfully use *only* your new authentication module for logins (including telnet), you must have the pam.conf file as below:
login  auth       required     /usr/lib/security/pam_NEW_auth.so.1

telnet auth       requisite    /usr/lib/security/pam_NEW_auth.so.1
telnet auth       required     /usr/lib/security/pam_unix.so.1

If you change the 'requisite' to 'required', then telnet logins will fail. This 'requisite' fix works, even if your 'NEW' style password is different from your Unix password. Bizarre, and very annoying.
login may pretend to be rlogin in some cases
If login is invoked with the -h SOME.HOST switch it uses the "rlogin" PAM service instead of login, *except* if also invoked with -d /some/tty. This is not documented in the man page, so if you've replaced telnetd and not enhanced it to pass -d to login, you may not end up using the expected modules. A bug has been opened but the id is not yet available.

If you so desire you can send email to shadow@dementia.org, which is where I read my mail.