From 6c17ca620dc67ef86428ebef2fffa2cff65ca708 Mon Sep 17 00:00:00 2001 From: Thorsten Kukuk Date: Wed, 28 Jun 2006 18:30:27 +0000 Subject: Relevant BUGIDs: Purpose of commit: bugfix Commit summary: --------------- Add missing chapters. --- doc/mwg/Linux-PAM_MWG.xml | 261 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 260 insertions(+), 1 deletion(-) (limited to 'doc') diff --git a/doc/mwg/Linux-PAM_MWG.xml b/doc/mwg/Linux-PAM_MWG.xml index fc4831a2..361db718 100644 --- a/doc/mwg/Linux-PAM_MWG.xml +++ b/doc/mwg/Linux-PAM_MWG.xml @@ -16,7 +16,7 @@ kukuk@thkukuk.de - Version 0.99, 26. June 2006 + Version 0.99, 28. June 2006 This manual documents what a programmer needs to know in order @@ -300,6 +300,265 @@ gcc -shared -o pam_module.so pam_module.o -lpam + + Programming notes + + Here we collect some pointers for the module writer to bear in mind + when writing/developing a Linux-PAM + compatible module. + + +
+ Security issues for module creation +
+ Sufficient resources + + Care should be taken to ensure that the proper execution + of a module is not compromised by a lack of system resources. + If a module is unable to open sufficient files to perform its + task, it should fail gracefully, or request additional resources. + Specifically, the quantities manipulated by the + setrlimit2 + family of commands should be taken into + consideration. + +
+
+ Who´s who? + + Generally, the module may wish to establish the identity of + the user requesting a service. This may not be the same as + the username returned by pam_get_user(). + Indeed, that is only going to be the name of the user under + whose identity the service will be given. This is not + necessarily the user that requests the service. + + + In other words, user X runs a program that is setuid-Y, it + grants the user to have the permissions of Z. A specific example + of this sort of service request is the su + program: user joe executes + su to become the user jane. + In this situation X=joe, Y=root + and Z=jane. Clearly, it is important that + the module does not confuse these different users and grant an + inappropriate level of privilege. + + + The following is the convention to be adhered to when juggling + user-identities. + + + + + X, the identity of the user invoking the service request. + This is the user identifier; returned by the function + + getuid2 + . + + + + + Y, the privileged identity of the application used to + grant the requested service. This is the + effective user identifier; + returned by the function + geteuid2 + . + + + + + Z, the user under whose identity the service will be granted. + This is the username returned by + pam_get_user() and also stored in the + Linux-PAM item, + PAM_USER. + + + + + Linux-PAM has a place for + an additional user identity that a module may care to make + use of. This is the PAM_RUSER item. + Generally, network sensitive modules/applications may wish + to set/read this item to establish the identity of the user + requesting a service from a remote location. + + + + + Note, if a module wishes to modify the identity of either the + uid or euid of the + running process, it should take care to restore the original + values prior to returning control to the + Linux-PAM library. + +
+
+ Using the conversation function + + Prior to calling the conversation function, the module should + reset the contents of the pointer that will return the applications + response. This is a good idea since the application may fail + to fill the pointer and the module should be in a position to + notice! + + + The module should be prepared for a failure from the + conversation. The generic error would be + PAM_CONV_ERR, but anything other than + PAM_SUCCESS should be treated as + indicating failure. + +
+
+ Authentication tokens + + To ensure that the authentication tokens are not left lying + around the items, PAM_AUTHTOK and + PAM_OLDAUTHTOK, are not available to + the application: they are defined in + <security/pam_modules.h>. This + is ostensibly for security reasons, but a maliciously + programmed application will always have access to all memory + of the process, so it is only superficially enforced. As a + general rule the module should overwrite authentication tokens + as soon as they are no longer needed. Especially before + free()'ing them. The + Linux-PAM library is + required to do this when either of these authentication + token items are (re)set. + + + Not to dwell too little on this concern; should the module + store the authentication tokens either as (automatic) function + variables or using pam_[gs]et_data() the + associated memory should be over-written explicitly before it + is released. In the case of the latter storage mechanism, the + associated cleanup() function should + explicitly overwrite the *data before + free()'ing it: for example, + +/* + * An example cleanup() function for releasing memory that was used to + * store a password. + */ + +int cleanup(pam_handle_t *pamh, void *data, int error_status) +{ + char *xx; + + if ((xx = data)) { + while (*xx) + *xx++ = '\0'; + free(data); + } + return PAM_SUCCESS; +} + + +
+
+
+ Use of <citerefentry> + <refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum> + </citerefentry> + + Only rarely should error information be directed to the user. + Usually, this is to be limited to + sorry you cannot login now + type messages. Information concerning errors in the configuration + file, /etc/pam.conf, or due to some system + failure encountered by the module, should be written to + + syslog3 + with facility-type + LOG_AUTHPRIV. + + + With a few exceptions, the level of logging is, at the discretion + of the module developer. Here is the recommended usage of different + logging levels: + + + + + As a general rule, errors encountered by a module should be + logged at the LOG_ERR level. However, + information regarding an unrecognized argument, passed to a + module from an entry in the /etc/pam.conf + file, is required to be logged at the + LOG_ERR level. + + + + + Debugging information, as activated by the + debug argument to the module in + /etc/pam.conf, should be logged + at the LOG_DEBUG level. + + + + + If a module discovers that its personal configuration + file or some system file it uses for information is + corrupted or somehow unusable, it should indicate this + by logging messages at level, LOG_ALERT. + + + + + Shortages of system resources, such as a failure to + manipulate a file or malloc() failures + should be logged at level LOG_CRIT. + + + + + Authentication failures, associated with an incorrectly + typed password should be logged at level, + LOG_NOTICE. + + + +
+
+ Modules that require system libraries + + Writing a module is much like writing an application. You + have to provide the "conventional hooks" for it to work + correctly, like pam_sm_authenticate() + etc., which would correspond to the main() + function in a normal function. + + + Typically, the author may want to link against some standard system + libraries. As when one compiles a normal program, this can be + done for modules too: you simply append the + -lXXX arguments + for the desired libraries when you create the shared module object. + To make sure a module is linked to the + libwhatever.so library + when it is dlopen()ed, try: + +% gcc -shared -o pam_module.so pam_module.o -lwhatever + + +
+
+ + + An example module + + At some point, we may include a fully commented example of a module in + this document. For now, please look at the modules directory of the + Linux-PAM sources. + + + See also -- cgit v1.2.3