Writing PAM Modules, Part Three
Pages: 1, 2
Initialise or terminate the session. This may entail tasks like writing log entries or cleaning up stored authentication tickets.
The close session function may be called by a different application than the one that opened the session, so data should be stored within the PAM system or in some non-volatile way.
PAM_EXTERN int pam_sm_open_session(pam_handle_t *pamh, int flags, int argc, const char **argv);
PAM_EXTERN int pam_sm_close_session(pam_handle_t *pamh, int flags, int argc, const char **argv);
If the module succeeds, it should return
PAM_SUCCESS. If it fails, it should return
pam_strerror function returns a human-readable string of text describing the error given in the parameter.
pam_fail_delay function is used to suggest a delay time after a failed authentication attempt. Should
pam_authenticate() fail, PAM delays returning control to the application by a randomized amount of time based on the longest delay time suggested in this PAM session. The application may also recommend a delay time.
extern const char *pam_strerror(pam_handle_t *pamh, int errnum); extern int pam_fail_delay(pam_handle_t *pamh, unsigned int micro_sec)
Applications need modules to return meaningful response codes.
- Everything went well, the module succeeded in its function, and (if appropriate) the user is who they say they are.
- Usually means the PAM handle has been corrupted.
- The user's account is out of date and they may not access the system.
- Authentication error.
- The module could not access the authentication information, perhaps due to hardware failure.
- The module has had token aging disabled.
- The module could not read the new authentication token.
- The authentication token could not be changed because of a lock.
- The old authentication token could not be retrieved.
- A variable could not be set/deleted because it was undefined, inaccessible, or not currently set.
- Memory allocation failure.
- The module could not set the user's credentials.
- The user's credentials have expired.
- The application is not permitted to authenticate the user, due to insufficient credentials.
- The module cannot read the user's credentials.
- The results of this module should be ignored.
- The module has reached its maximum number of retries. Do not continue to attempt to authenticate this user.
- The authentication token has expired, and should be renewed.
- Permission denied, or a required parameter was a
- This module cannot fulfil this type of request.
- Usually means an invalid PAM handle.
- The module could not update the authentication token, therefore none of the tokens were updated.
- The module does not recognize the user.
Authentication systems need to be securely coded. There are a few concerns mentioned here, and others in the Linux-PAM Module Developer's Guide. Read both of these, and also be careful to have someone who knows secure programming check your code before you release it to production use.
Be careful to authenticate the correct user. The username returned by
pam_get_user()is the person who will be receiving the service. This is not necessarily the same as the
When receiving an authentication token, be sure to zero the data space once you no longer need it, and certainly before you free it.
Ensure that the conversation response is zeroed, or otherwise has predictable content that you can test to be sure the application has returned an actual response and you're not reading junk data.
syslograther than user messages for most errors.
Ensure that your module tries to fail gracefully if it runs out of system resources.
Be aware of the programming issues for statically-linked programs. Many modules will be statically loaded in practice.
This is part three of a three part series on writing PAM modules. Start by writing small, useful modules that do one thing well. What do you wish your application would do when you start it?
Jennifer Vesperman is the author of Essential CVS. She writes for the O'Reilly Network, the Linux Documentation Project, and occasionally Linux.Com.
Return to the Linux DevCenter.