ChangeLog | 10 + doc/man/pam.3 | 134 ++++++--- doc/man/pam.3.xml | 11 +- doc/man/pam.conf-syntax.xml | 4 +- doc/man/pam.conf.5 | 92 ++++-- libpam/Makefile.am | 2 +- libpam/pam_audit.c | 15 +- libpam/pam_data.c | 51 +++- modules/pam_localuser/pam_localuser.8 | 38 ++- modules/pam_localuser/pam_localuser.8.xml | 4 +- modules/pam_localuser/pam_localuser.c | 27 ++- modules/pam_mkhomedir/pam_mkhomedir.c | 7 +- modules/pam_motd/README | 2 +- modules/pam_motd/pam_motd.8 | 16 +- modules/pam_motd/pam_motd.8.xml | 2 +- modules/pam_umask/pam_umask.c | 23 +- modules/pam_wheel/README | 2 +- modules/pam_wheel/pam_wheel.8 | 2 +- modules/pam_wheel/pam_wheel.8.xml | 2 +- po/de.po | 2 +- tests/.cvsignore | 1 + tests/Makefile.am | 5 +- tests/tst-pam_set_data.c | 488 +++++++++++++++++++++++++++++ 23 files changed, 816 insertions(+), 124 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2b5b143..ddc4247 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2006-09-09 Dmitry V. Levin + + * modules/pam_wheel/pam_wheel.8.xml: Fix typo. + * modules/pam_wheel/pam_wheel.8: Likewise. + * modules/pam_wheel/README: Likewise. + +2006-09-08 Thorsten Kukuk + + * po/de.po: Fix typo. + 2006-09-06 Thorsten Kukuk * release version 0.99.6.3 diff --git a/doc/man/pam.3 b/doc/man/pam.3 index 235daff..f1cd729 100644 --- a/doc/man/pam.3 +++ b/doc/man/pam.3 @@ -1,11 +1,11 @@ .\" Title: pam .\" Author: -.\" Generator: DocBook XSL Stylesheets v1.70.1 -.\" Date: 06/27/2006 +.\" Generator: DocBook XSL Stylesheets v1.71.0 +.\" Date: 10/26/2006 .\" Manual: Linux\-PAM Manual .\" Source: Linux\-PAM Manual .\" -.TH "PAM" "3" "06/27/2006" "Linux\-PAM Manual" "Linux\-PAM Manual" +.TH "PAM" "3" "10/26/2006" "Linux\-PAM Manual" "Linux\-PAM Manual" .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) @@ -48,7 +48,6 @@ function creates the PAM context and initiates the PAM transaction. It is the fi The \fBpam_end\fR(3) function terminates the PAM transaction and is the last function an application should call in the PAM contenxt. Upon return the handle pamh is no longer valid and all memory associated with it will be invalid. It can be called at any time to terminate a PAM transaction. -.\" end of SS subsection "Initialization and Cleanup" .SS "Authentication" .PP The @@ -58,26 +57,22 @@ function is used to authenticate the user. The user is required to provide an au The \fBpam_setcred\fR(3) function manages the userscredentials. -.\" end of SS subsection "Authentication" .SS "Account Management" .PP The \fBpam_acct_mgmt\fR(3) function is used to determine if the users account is valid. It checks for authentication token and account expiration and verifies access restrictions. It is typically called after the user has been authenticated. -.\" end of SS subsection "Account Management" .SS "Password Management" .PP The \fBpam_chauthtok\fR(3) function is used to change the authentication token for a given user on request or because the token has expired. -.\" end of SS subsection "Password Management" .SS "Session Management" .PP The \fBpam_open_session\fR(3) function sets up a user session for a previously successful authenticated user. The session should later be terminated with a call to \fBpam_close_session\fR(3). -.\" end of SS subsection "Session Management" .SS "Conversation" .PP The PAM library uses an application\-defined callback to allow a direct communication between a loaded module and the application. This callback is specified by the @@ -87,7 +82,6 @@ passed to at the start of the transaction. See \fBpam_conv\fR(3) for details. -.\" end of SS subsection "Conversation" .SS "Data Objects" .PP The @@ -97,11 +91,14 @@ and functions allows applications and PAM service modules to set and retrieve PAM informations. .PP The +\fBpam_get_user\fR(3) +function is the preferred method to obtain the username. +.PP +The \fBpam_set_data\fR(3) and \fBpam_get_data\fR(3) functions allows PAM service modules to set and retrieve free\-form data from one invocation to another. -.\" end of SS subsection "Data Objects" .SS "Environment and Error Management" .PP The @@ -114,97 +111,154 @@ functions are for maintaining a set of private environment variables. The \fBpam_strerror\fR(3) function returns a pointer to a string describing the given PAM error code. -.\" end of SS subsection "Environment and Error Management" .SH "RETURN VALUES" .PP The following return codes are known by PAM: -.TP 3n +.PP PAM_ABORT +.RS 3n Critical error, immediate abort. -.TP 3n +.RE +.PP PAM_ACCT_EXPIRED +.RS 3n User account has expired. -.TP 3n +.RE +.PP PAM_AUTHINFO_UNAVAIL +.RS 3n Authentication service cannot retrieve authentication info. -.TP 3n +.RE +.PP PAM_AUTHTOK_DISABLE_AGING +.RS 3n Authentication token aging disabled. -.TP 3n +.RE +.PP PAM_AUTHTOK_ERR +.RS 3n Authentication token manipulation error. -.TP 3n +.RE +.PP PAM_AUTHTOK_EXPIRED +.RS 3n Authentication token expired. -.TP 3n +.RE +.PP PAM_AUTHTOK_LOCK_BUSY +.RS 3n Authentication token lock busy. -.TP 3n +.RE +.PP PAM_AUTHTOK_RECOVERY_ERR +.RS 3n Authentication information cannot be recovered. -.TP 3n +.RE +.PP PAM_AUTH_ERR +.RS 3n Authentication failure. -.TP 3n +.RE +.PP PAM_BUF_ERR +.RS 3n Memory buffer error. -.TP 3n +.RE +.PP PAM_CONV_ERR +.RS 3n Conversation failure. -.TP 3n +.RE +.PP PAM_CRED_ERR +.RS 3n Failure setting user credentials. -.TP 3n +.RE +.PP PAM_CRED_EXPIRED +.RS 3n User credentials expired. -.TP 3n +.RE +.PP PAM_CRED_INSUFFICIENT +.RS 3n Insufficient credentials to access authentication data. -.TP 3n +.RE +.PP PAM_CRED_UNAVAIL +.RS 3n Authentication service cannot retrieve user credentials. -.TP 3n +.RE +.PP PAM_IGNORE +.RS 3n The return value should be ignored by PAM dispatch. -.TP 3n +.RE +.PP PAM_MAXTRIES +.RS 3n Have exhausted maximum number of retries for service. -.TP 3n +.RE +.PP PAM_MODULE_UNKNOWN +.RS 3n Module is unknown. -.TP 3n +.RE +.PP PAM_NEW_AUTHTOK_REQD +.RS 3n Authentication token is no longer valid; new one required. -.TP 3n +.RE +.PP PAM_NO_MODULE_DATA +.RS 3n No module specific data is present. -.TP 3n +.RE +.PP PAM_OPEN_ERR +.RS 3n Failed to load module. -.TP 3n +.RE +.PP PAM_PERM_DENIED +.RS 3n Permission denied. -.TP 3n +.RE +.PP PAM_SERVICE_ERR +.RS 3n Error in service module. -.TP 3n +.RE +.PP PAM_SESSION_ERR +.RS 3n Cannot make/remove an entry for the specified session. -.TP 3n +.RE +.PP PAM_SUCCESS +.RS 3n Success. -.TP 3n +.RE +.PP PAM_SYMBOL_ERR +.RS 3n Symbol not found. -.TP 3n +.RE +.PP PAM_SYSTEM_ERR +.RS 3n System error. -.TP 3n +.RE +.PP PAM_TRY_AGAIN +.RS 3n Failed preliminary check by password service. -.TP 3n +.RE +.PP PAM_USER_UNKNOWN +.RS 3n User not known to the underlying authentication module. +.RE .SH "SEE ALSO" .PP diff --git a/doc/man/pam.3.xml b/doc/man/pam.3.xml index ab9e3d2..3ae2d34 100644 --- a/doc/man/pam.3.xml +++ b/doc/man/pam.3.xml @@ -152,8 +152,15 @@ pam_get_item3 - functions allows applications and PAM service modules to set and retrieve - PAM informations. + functions allows applications and PAM service modules to set and + retrieve PAM informations. + + + The + + pam_get_user3 + + function is the preferred method to obtain the username. The diff --git a/doc/man/pam.conf-syntax.xml b/doc/man/pam.conf-syntax.xml index b422cba..60c64b7 100644 --- a/doc/man/pam.conf-syntax.xml +++ b/doc/man/pam.conf-syntax.xml @@ -155,7 +155,9 @@ prior required module has failed the success of this one is ignored). A failure of this module is not deemed as fatal to satisfying the - application that this type has succeeded. + application that this type has succeeded. If the module succeeds + the PAM framework returns success to the application immediately + without trying any other modules. diff --git a/doc/man/pam.conf.5 b/doc/man/pam.conf.5 index 2ea4018..3a76ba4 100644 --- a/doc/man/pam.conf.5 +++ b/doc/man/pam.conf.5 @@ -1,11 +1,11 @@ .\" Title: pam.conf .\" Author: -.\" Generator: DocBook XSL Stylesheets v1.70.1 -.\" Date: 06/27/2006 +.\" Generator: DocBook XSL Stylesheets v1.71.1 +.\" Date: 01/16/2007 .\" Manual: Linux\-PAM Manual .\" Source: Linux\-PAM Manual .\" -.TH "PAM.CONF" "5" "06/27/2006" "Linux\-PAM Manual" "Linux\-PAM Manual" +.TH "PAM.CONF" "5" "01/16/2007" "Linux\-PAM Manual" "Linux\-PAM Manual" .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) @@ -67,18 +67,26 @@ entries) will be associated with the given service\-application. The \fItype\fR is the management group that the rule corresponds to. It is used to specify which of the management groups the subsequent module is to be associated with. Valid entries are: -.TP 3n +.PP account +.RS 4 this module type performs non\-authentication based account management. It is typically used to restrict/permit access to a service based on the time of day, currently available system resources (maximum number of users) or perhaps the location of the applicant user \-\- 'root' login only on the console. -.TP 3n +.RE +.PP auth +.RS 4 this module type provides two aspects of authenticating the user. Firstly, it establishes that the user is who they claim to be, by instructing the application to prompt the user for a password or other means of identification. Secondly, the module can grant group membership or other privileges through its credential granting properties. -.TP 3n +.RE +.PP password +.RS 4 this module type is required for updating the authentication token associated with the user. Typically, there is one module for each 'challenge/response' based authentication (auth) type. -.TP 3n +.RE +.PP session +.RS 4 this module type is associated with doing things that need to be done for the user before/after they can be given service. Such things include the logging of information concerning the opening/closing of some data exchange with a user, mounting directories, etc. +.RE .PP The third field, \fIcontrol\fR, indicates the behavior of the PAM\-API should the module fail to succeed in its authentication task. There are two types of syntax for this control field: the simple one has a single simple keyword; the more complicated one involves a square\-bracketed selection of @@ -88,37 +96,47 @@ pairs. For the simple (historical) syntax valid \fIcontrol\fR values are: -.TP 3n +.PP required +.RS 4 failure of such a PAM will ultimately lead to the PAM\-API returning failure but only after the remaining \fIstacked\fR modules (for this \fIservice\fR and \fItype\fR) have been invoked. -.TP 3n +.RE +.PP requisite +.RS 4 like \fIrequired\fR, however, in the case that such a module returns a failure, control is directly returned to the application. The return value is that associated with the first required or requisite module to fail. Note, this flag can be used to protect against the possibility of a user getting the opportunity to enter a password over an unsafe medium. It is conceivable that such behavior might inform an attacker of valid accounts on a system. This possibility should be weighed against the not insignificant concerns of exposing a sensitive password in a hostile environment. -.TP 3n +.RE +.PP sufficient +.RS 4 success of such a module is enough to satisfy the authentication requirements of the stack of modules (if a prior \fIrequired\fR module has failed the success of this one is -\fIignored\fR). A failure of this module is not deemed as fatal to satisfying the application that this type has succeeded. -.TP 3n +\fIignored\fR). A failure of this module is not deemed as fatal to satisfying the application that this type has succeeded. If the module succeeds the PAM framework returns success to the application immediately without trying any other modules. +.RE +.PP optional +.RS 4 the success or failure of this module is only important if it is the only module in the stack associated with this \fIservice\fR+\fItype\fR. -.TP 3n +.RE +.PP include +.RS 4 include all lines of given type from the configuration file specified as an argument to this control. +.RE .PP For the more complicated syntax valid \fIcontrol\fR values have the following form: .sp -.RS 3n +.RS 4 .nf [value1=action1 value2=action2 ...] @@ -170,39 +188,59 @@ can be: an unsigned integer, \fIn\fR, signifying an action of 'jump over the next \fIn\fR modules in the stack', or take one of the following forms: -.TP 3n +.PP ignore +.RS 4 when used with a stack of modules, the module's return status will not contribute to the return code the application obtains. -.TP 3n +.RE +.PP bad +.RS 4 this action indicates that the return code should be thought of as indicative of the module failing. If this module is the first in the stack to fail, its status value will be used for that of the whole stack. -.TP 3n +.RE +.PP die +.RS 4 equivalent to bad with the side effect of terminating the module stack and PAM immediately returning to the application. -.TP 3n +.RE +.PP ok +.RS 4 this tells PAM that the administrator thinks this return code should contribute directly to the return code of the full stack of modules. In other words, if the former state of the stack would lead to a return of \fIPAM_SUCCESS\fR, the module's return code will override this value. Note, if the former state of the stack holds some value that is indicative of a modules failure, this 'ok' value will not be used to override that value. -.TP 3n +.RE +.PP done +.RS 4 equivalent to ok with the side effect of terminating the module stack and PAM immediately returning to the application. -.TP 3n +.RE +.PP reset +.RS 4 clear all memory of the state of the module stack and start again with the next stacked module. +.RE .PP Each of the four keywords: required; requisite; sufficient; and optional, have an equivalent expression in terms of the [...] syntax. They are as follows: -.TP 3n +.PP required +.RS 4 [success=ok new_authtok_reqd=ok ignore=ignore default=bad] -.TP 3n +.RE +.PP requisite +.RS 4 [success=ok new_authtok_reqd=ok ignore=ignore default=die] -.TP 3n +.RE +.PP sufficient +.RS 4 [success=done new_authtok_reqd=done default=ignore] -.TP 3n +.RE +.PP optional +.RS 4 [success=ok new_authtok_reqd=ok default=ignore] +.RE .PP \fImodule\-path\fR @@ -215,7 +253,7 @@ or \fImodule\-arguments\fR are a space separated list of tokens that can be used to modify the specific behavior of the given PAM. Such arguments will be documented for each individual module. Note, if you wish to include spaces in an argument, you should surround that argument with square brackets. .sp -.RS 3n +.RS 4 .nf squid auth required pam_mysql.so user=passwd_query passwd=mada \\ db=eminence [query=select user_name from internet_service \\ @@ -227,7 +265,7 @@ are a space separated list of tokens that can be used to modify the specific beh .PP When using this convention, you can include `[' characters inside the string, and if you wish to include a `]' character inside the string that will survive the argument parsing, you should use `\\['. In other words: .sp -.RS 3n +.RS 4 .nf [..[..\\]..] \-\-> ..[..].. @@ -245,7 +283,7 @@ The syntax of each file in /etc/pam.d/ is similar to that of the \fI/etc/pam.conf\fR file and is made up of lines of the following form: .sp -.RS 3n +.RS 4 .nf type control module\-path module\-arguments diff --git a/libpam/Makefile.am b/libpam/Makefile.am index 3c81693..8c603ef 100644 --- a/libpam/Makefile.am +++ b/libpam/Makefile.am @@ -20,7 +20,7 @@ include_HEADERS = $(addprefix include/security/, _pam_compat.h _pam_macros.h _pa noinst_HEADERS = pam_prelude.h pam_private.h pam_tokens.h \ pam_modutil_private.h pam_static_modules.h -libpam_la_LDFLAGS = -no-undefined -version-info 81:5:81 @LIBAUDIT@ +libpam_la_LDFLAGS = -no-undefined -version-info 81:6:81 @LIBAUDIT@ if STATIC_MODULES libpam_la_LDFLAGS += `ls ../modules/pam_*/*.lo` \ @LIBDB@ @LIBCRYPT@ @LIBNSL@ @LIBCRACK@ -lutil diff --git a/libpam/pam_audit.c b/libpam/pam_audit.c index 4399e5c..ff1486a 100644 --- a/libpam/pam_audit.c +++ b/libpam/pam_audit.c @@ -22,18 +22,25 @@ #define PAMAUDIT_LOGGED 1 static int -_pam_audit_writelog(pam_handle_t *pamh, int audit_fd, int type, +_pam_audit_writelog(pam_handle_t *pamh, int audit_fd, int type, const char *message, int retval) { + static int old_errno = -1; int rc; char buf[256]; - snprintf(buf, sizeof(buf), "PAM: %s acct=%s ", message, + snprintf(buf, sizeof(buf), "PAM: %s acct=%s ", message, (retval != PAM_USER_UNKNOWN && pamh->user) ? pamh->user : "?"); rc = audit_log_user_message( audit_fd, type, buf, pamh->rhost, NULL, pamh->tty, retval == PAM_SUCCESS ); + if (rc == -1 && errno != old_errno) + { + old_errno = errno; + pam_syslog(pamh, LOG_CRIT, "audit_log_user_message() failed: %m"); + } + pamh->audit_state |= PAMAUDIT_LOGGED; return rc; } @@ -59,7 +66,7 @@ _pam_auditlog(pam_handle_t *pamh, int action, int retval, int flags) pam_syslog(pamh, LOG_CRIT, "audit_open() failed: %m"); return PAM_SYSTEM_ERR; } - + switch (action) { case PAM_AUTHENTICATE: message = "authentication"; @@ -105,7 +112,7 @@ _pam_auditlog(pam_handle_t *pamh, int action, int retval, int flags) if (_pam_audit_writelog(pamh, audit_fd, type, message, retval) < 0) retval = PAM_SYSTEM_ERR; - + audit_close(audit_fd); return retval; } diff --git a/libpam/pam_data.c b/libpam/pam_data.c index 28b3680..30570af 100644 --- a/libpam/pam_data.c +++ b/libpam/pam_data.c @@ -1,9 +1,38 @@ -/* pam_data.c */ - /* - * $Id$ + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, and the entire permission notice in its entirety, + * including the disclaimer of warranties. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * ALTERNATIVELY, this product may be distributed under the terms of + * the GNU Public License, in which case the provisions of the GPL are + * required INSTEAD OF the above restrictions. (This clause is + * necessary due to a potential bad interaction between the GPL and + * the restrictions contained in a BSD-style copyright.) + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include "config.h" + #include "pam_private.h" #include @@ -19,7 +48,7 @@ static struct pam_data *_pam_locate_data(const pam_handle_t *pamh, IF_NO_PAMH("_pam_locate_data", pamh, NULL); data = pamh->data; - + while (data) { if (!strcmp(data->name, name)) { return data; @@ -37,7 +66,7 @@ int pam_set_data( void (*cleanup)(pam_handle_t *pamh, void *data, int error_status)) { struct pam_data *data_entry; - + D(("called")); IF_NO_PAMH("pam_set_data", pamh, PAM_SYSTEM_ERR); @@ -47,6 +76,12 @@ int pam_set_data( return PAM_SYSTEM_ERR; } + /* module_data_name should not be NULL */ + if (module_data_name == NULL) { + D(("called with NULL as module_data_name")); + return PAM_SYSTEM_ERR; + } + /* first check if there is some data already. If so clean it up */ if ((data_entry = _pam_locate_data(pamh, module_data_name))) { @@ -94,6 +129,12 @@ int pam_get_data( return PAM_SYSTEM_ERR; } + /* module_data_name should not be NULL */ + if (module_data_name == NULL) { + D(("called with NULL as module_data_name")); + return PAM_SYSTEM_ERR; + } + data = _pam_locate_data(pamh, module_data_name); if (data) { *datap = data->data; diff --git a/modules/pam_localuser/pam_localuser.8 b/modules/pam_localuser/pam_localuser.8 index c10cd07..e88f0b5 100644 --- a/modules/pam_localuser/pam_localuser.8 +++ b/modules/pam_localuser/pam_localuser.8 @@ -1,11 +1,11 @@ .\" Title: pam_localuser .\" Author: -.\" Generator: DocBook XSL Stylesheets v1.70.1 -.\" Date: 06/09/2006 +.\" Generator: DocBook XSL Stylesheets v1.71.0 +.\" Date: 12/13/2006 .\" Manual: Linux\-PAM Manual .\" Source: Linux\-PAM Manual .\" -.TH "PAM_LOCALUSER" "8" "06/09/2006" "Linux\-PAM Manual" "Linux\-PAM Manual" +.TH "PAM_LOCALUSER" "8" "12/13/2006" "Linux\-PAM Manual" "Linux\-PAM Manual" .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) @@ -22,31 +22,41 @@ pam_localuser is a PAM module to help implementing site\-wide login policies, wh This could also be implemented using pam_listfile.so and a very short awk script invoked by cron, but it's common enough to have been separated out. .SH "OPTIONS" .PP -.TP 3n +.PP \fBdebug\fR +.RS 3n Print debug information. -.TP 3n +.RE +.PP \fBfile=\fR\fB\fI/path/passwd\fR\fR +.RS 3n Use a file other than \fI/etc/passwd\fR. +.RE .SH "MODULE SERVICES PROVIDED" .PP -The -\fBauth\fR +All services (\fBaccount\fR, +\fBauth\fR, +\fBpassword\fR and -\fBaccount\fR -services are supported. +\fBsession\fR) are supported. .SH "RETURN VALUES" .PP -.TP 3n +.PP PAM_SUCCESS +.RS 3n The new localuser was set successfull. -.TP 3n +.RE +.PP PAM_SERVICE_ERR +.RS 3n No username was given. -.TP 3n +.RE +.PP PAM_USER_UNKNOWN +.RS 3n User not known. +.RE .SH "EXAMPLES" .PP Add the following line to @@ -62,9 +72,11 @@ account required pam_wheel.so .RE .sp .SH "FILES" -.TP 3n +.PP \fI/etc/passwd\fR +.RS 3n Local user account information. +.RE .SH "SEE ALSO" .PP diff --git a/modules/pam_localuser/pam_localuser.8.xml b/modules/pam_localuser/pam_localuser.8.xml index 22ed443..ac00ce9 100644 --- a/modules/pam_localuser/pam_localuser.8.xml +++ b/modules/pam_localuser/pam_localuser.8.xml @@ -83,8 +83,8 @@ MODULE SERVICES PROVIDED - The auth and - account services are supported. + All services (, , + and ) are supported. diff --git a/modules/pam_localuser/pam_localuser.c b/modules/pam_localuser/pam_localuser.c index f99f442..aa43bc4 100644 --- a/modules/pam_localuser/pam_localuser.c +++ b/modules/pam_localuser/pam_localuser.c @@ -136,6 +136,27 @@ pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, int argc, const char **argv) return pam_sm_authenticate(pamh, flags, argc, argv); } +PAM_EXTERN int +pam_sm_open_session (pam_handle_t *pamh, int flags, + int argc, const char **argv) +{ + return pam_sm_authenticate(pamh, flags, argc, argv); +} + +PAM_EXTERN int +pam_sm_close_session (pam_handle_t *pamh, int flags, + int argc, const char **argv) +{ + return pam_sm_authenticate(pamh, flags, argc, argv); +} + +PAM_EXTERN int +pam_sm_chauthtok (pam_handle_t *pamh, int flags, + int argc, const char **argv) +{ + return pam_sm_authenticate(pamh, flags, argc, argv); +} + #ifdef PAM_STATIC /* static module data */ @@ -145,9 +166,9 @@ struct pam_module _pam_localuser_modstruct = { pam_sm_authenticate, pam_sm_setcred, pam_sm_acct_mgmt, - NULL, - NULL, - NULL, + pam_sm_open_session, + pam_sm_close_session, + pam_sm_chauthtok }; #endif diff --git a/modules/pam_mkhomedir/pam_mkhomedir.c b/modules/pam_mkhomedir/pam_mkhomedir.c index 216f252..e5901a8 100644 --- a/modules/pam_mkhomedir/pam_mkhomedir.c +++ b/modules/pam_mkhomedir/pam_mkhomedir.c @@ -103,7 +103,7 @@ rec_mkdir (const char *dir, mode_t mode) cp = strrchr (parent, '/'); - if (cp != NULL) + if (cp != NULL && cp != parent) { struct stat st; @@ -137,12 +137,13 @@ create_homedir (pam_handle_t * pamh, int ctrl, /* Mention what is happening, if the notification fails that is OK */ if ((ctrl & MKHOMEDIR_QUIET) != MKHOMEDIR_QUIET) - (void) pam_info(pamh, "Creating directory '%s'.", dest); + pam_info(pamh, _("Creating directory '%s'."), dest); /* Create the new directory */ if (rec_mkdir (dest,0755) != 0) { - pam_syslog(pamh, LOG_DEBUG, "unable to create directory %s: %m", dest); + pam_error(pamh, _("Unable to create directory %s: %m"), dest); + pam_syslog(pamh, LOG_ERR, "unable to create directory %s: %m", dest); return PAM_PERM_DENIED; } diff --git a/modules/pam_motd/README b/modules/pam_motd/README index 74947da..414ad6f 100644 --- a/modules/pam_motd/README +++ b/modules/pam_motd/README @@ -18,7 +18,7 @@ EXAMPLES The suggested usage for /etc/pam.d/login is: -session optoinal pam_motd.so motd=/etc/motd +session optional pam_motd.so motd=/etc/motd AUTHOR diff --git a/modules/pam_motd/pam_motd.8 b/modules/pam_motd/pam_motd.8 index 62fad5b..74bfb58 100644 --- a/modules/pam_motd/pam_motd.8 +++ b/modules/pam_motd/pam_motd.8 @@ -1,11 +1,11 @@ .\" Title: pam_motd .\" Author: -.\" Generator: DocBook XSL Stylesheets v1.70.1 -.\" Date: 06/03/2006 +.\" Generator: DocBook XSL Stylesheets v1.71.0 +.\" Date: 10/26/2006 .\" Manual: Linux\-PAM Manual .\" Source: Linux\-PAM Manual .\" -.TH "PAM_MOTD" "8" "06/03/2006" "Linux\-PAM Manual" "Linux\-PAM Manual" +.TH "PAM_MOTD" "8" "10/26/2006" "Linux\-PAM Manual" "Linux\-PAM Manual" .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) @@ -21,20 +21,24 @@ pam_motd is a PAM module that can be used to display arbitrary motd (message of \fI/etc/motd\fR file is shown. The message size is limited to 64KB. .SH "OPTIONS" -.TP 3n +.PP \fBmotd=\fR\fB\fI/path/filename\fR\fR +.RS 3n The \fI/path/filename\fR file is displayed as message of the day. +.RE .SH "MODULE SERVICES PROVIDED" .PP Only the \fBsession\fR service is supported. .SH "RETURN VALUES" -.TP 3n +.PP PAM_IGNORE +.RS 3n This is the only return value of this module. +.RE .SH "EXAMPLES" .PP The suggested usage for @@ -43,7 +47,7 @@ is: .sp .RS 3n .nf -session optoinal pam_motd.so motd=/etc/motd +session optional pam_motd.so motd=/etc/motd .fi .RE diff --git a/modules/pam_motd/pam_motd.8.xml b/modules/pam_motd/pam_motd.8.xml index 3b60a96..7bd6798 100644 --- a/modules/pam_motd/pam_motd.8.xml +++ b/modules/pam_motd/pam_motd.8.xml @@ -81,7 +81,7 @@ The suggested usage for /etc/pam.d/login is: -session optoinal pam_motd.so motd=/etc/motd +session optional pam_motd.so motd=/etc/motd diff --git a/modules/pam_umask/pam_umask.c b/modules/pam_umask/pam_umask.c index c5fa773..fdeb3c5 100644 --- a/modules/pam_umask/pam_umask.c +++ b/modules/pam_umask/pam_umask.c @@ -15,8 +15,8 @@ * written permission. * * ALTERNATIVELY, this product may be distributed under the terms of - * the GNU Public License, in which case the provisions of the GPL are - * required INSTEAD OF the above restrictions. (This clause is + * the GNU Public License V2, in which case the provisions of the GPL + * are required INSTEAD OF the above restrictions. (This clause is * necessary due to a potential bad interaction between the GPL and * the restrictions contained in a BSD-style copyright.) * @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -55,6 +56,10 @@ #include #include +#define BUF_SIZE 4096 +#define LOGIN_DEFS "/etc/login.defs" +#define LOGIN_CONF "/etc/default/login" + struct options_t { int debug; int usergroups; @@ -105,7 +110,7 @@ search_key (const char *filename) if (buf == NULL) { - buflen = 8096; + buflen = BUF_SIZE; buf = malloc (buflen); } buf[0] = '\0'; @@ -145,8 +150,7 @@ search_key (const char *filename) } fclose (fp); - if (buf) - free (buf); + free (buf); return retval; } @@ -161,9 +165,9 @@ get_options (const pam_handle_t *pamh, options_t *options, parse_option (pamh, *argv, options); if (options->umask == NULL) - options->umask = search_key ("/etc/login.defs"); + options->umask = search_key (LOGIN_DEFS); if (options->umask == NULL) - options->umask = search_key ("/etc/default/login"); + options->umask = search_key (LOGIN_CONF); return 0; } @@ -175,8 +179,9 @@ set_umask (const char *value) mode_t mask; char *endptr; - mask = strtol (value, &endptr, 8) & 0777; - if ((mask == 0) && (value_orig == endptr)) + mask = strtoul (value, &endptr, 8) & 0777; + if (((mask == 0) && (value_orig == endptr)) || + ((mask == ULONG_MAX) && (errno == ERANGE))) return; umask (mask); return; diff --git a/modules/pam_wheel/README b/modules/pam_wheel/README index db11820..6a2b21c 100644 --- a/modules/pam_wheel/README +++ b/modules/pam_wheel/README @@ -26,7 +26,7 @@ deny group=name Instead of checking the wheel or GID 0 groups, use the name group to - perform the authentification. + perform the authentication. root_only diff --git a/modules/pam_wheel/pam_wheel.8 b/modules/pam_wheel/pam_wheel.8 index aaecc1a..ae29c37 100644 --- a/modules/pam_wheel/pam_wheel.8 +++ b/modules/pam_wheel/pam_wheel.8 @@ -38,7 +38,7 @@ was also specified, in which case we return PAM_SUCCESS). \fBgroup=\fR\fB\fIname\fR\fR Instead of checking the wheel or GID 0 groups, use the \fB\fIname\fR\fR -group to perform the authentification. +group to perform the authentication. .TP 3n \fBroot_only\fR The check for wheel membership is done only. diff --git a/modules/pam_wheel/pam_wheel.8.xml b/modules/pam_wheel/pam_wheel.8.xml index f3d2fb4..bf8b734 100644 --- a/modules/pam_wheel/pam_wheel.8.xml +++ b/modules/pam_wheel/pam_wheel.8.xml @@ -87,7 +87,7 @@ Instead of checking the wheel or GID 0 groups, use the group - to perform the authentification. + to perform the authentication. diff --git a/po/de.po b/po/de.po index 2c468b0..cb84ff5 100644 --- a/po/de.po +++ b/po/de.po @@ -303,7 +303,7 @@ msgstr "Nur Änderungen bei der Groß-/Kleinschreibung" #: modules/pam_cracklib/pam_cracklib.c:395 msgid "is too similar to the old one" -msgstr "ist der/m alten zu ähnlich" +msgstr "ist dem alten zu ähnlich" #: modules/pam_cracklib/pam_cracklib.c:398 msgid "is too simple" diff --git a/tests/.cvsignore b/tests/.cvsignore index 9833ca6..8907f47 100644 --- a/tests/.cvsignore +++ b/tests/.cvsignore @@ -14,6 +14,7 @@ tst-pam_get_item tst-pam_get_user tst-pam_getenvlist tst-pam_open_session +tst-pam_set_data tst-pam_set_item tst-pam_setcred tst-pam_start diff --git a/tests/Makefile.am b/tests/Makefile.am index 4f0d6a5..a5b8d08 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -2,7 +2,8 @@ # Copyright (c) 2006 Thorsten Kukuk # -AM_CFLAGS = -DLIBPAM_COMPILE -I$(top_srcdir)/libpam/include +AM_CFLAGS = -DLIBPAM_COMPILE -I$(top_srcdir)/libpam/include \ + -I$(top_srcdir)/libpam AM_LDFLAGS = -L$(top_builddir)/libpam -lpam CLEANFILES = *~ @@ -10,7 +11,7 @@ CLEANFILES = *~ TESTS = tst-pam_start tst-pam_end tst-pam_fail_delay tst-pam_open_session \ tst-pam_close_session tst-pam_acct_mgmt tst-pam_authenticate \ tst-pam_chauthtok tst-pam_setcred tst-pam_get_item tst-pam_set_item \ - tst-pam_getenvlist tst-pam_get_user + tst-pam_getenvlist tst-pam_get_user tst-pam_set_data check_PROGRAMS = ${TESTS} tst-dlopen diff --git a/tests/tst-pam_set_data.c b/tests/tst-pam_set_data.c new file mode 100644 index 0000000..3b30dcc --- /dev/null +++ b/tests/tst-pam_set_data.c @@ -0,0 +1,488 @@ +/* + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, and the entire permission notice in its entirety, + * including the disclaimer of warranties. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * ALTERNATIVELY, this product may be distributed under the terms of + * the GNU Public License, in which case the provisions of the GPL are + * required INSTEAD OF the above restrictions. (This clause is + * necessary due to a potential bad interaction between the GPL and + * the restrictions contained in a BSD-style copyright.) + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include + +#include +#include +#include + +static int cleanup_was_called = 0; +static int cleanup3_was_called = 0; +static int cleanup3_retval = 0; +static int cleanup6_was_called = 0; +static int cleanup6_retval = 0; +static int cleanup7_was_called = 0; +static int cleanup7_retval = 0; +static int cleanup7b_was_called = 0; +static int cleanup7b_retval = 0; +static int cleanup8_was_called = 0; +static int cleanup8_retval = 0; + +static void +tst_cleanup (pam_handle_t *pamh UNUSED, void *data, int error_status) +{ + cleanup_was_called = 1; + fprintf (stderr, "tst_cleanup was called: data=\"%s\", error_status=%d\n", + (char *)data, error_status); +} + +static void +tst_cleanup_3 (pam_handle_t *pamh UNUSED, void *data, int error_status) +{ + cleanup3_was_called = 1; + + if (strcmp (data, "test3") != 0) + { + fprintf (stderr, "tst_cleanup_3 called with wrong data, got \"%s\"\n", + (char *)data); + cleanup3_retval = 1; + return; + } + + free (data); + + if (error_status & PAM_DATA_REPLACE) + { + fprintf (stderr, "tst_cleanup_3 called with PAM_DATA_REPLACE set\n"); + cleanup3_retval = 1; + return; + } + + if (error_status & PAM_DATA_SILENT) + { + fprintf (stderr, "tst_cleanup_3 called with PAM_DATA_SILENT set\n"); + cleanup3_retval = 1; + return; + } + + if (error_status != 0) + { + fprintf (stderr, "tst_cleanup_3 called with error_status set: %d\n", + error_status); + cleanup3_retval = 1; + return; + } +} + +static void +tst_cleanup_6 (pam_handle_t *pamh UNUSED, void *data, int error_status) +{ + cleanup6_was_called = 1; + + if (error_status & PAM_DATA_SILENT) + { + fprintf (stderr, "tst_cleanup_6 called with PAM_DATA_SILENT set\n"); + cleanup6_retval = 1; + return; + } + + if (error_status & PAM_DATA_REPLACE) + { + if (strcmp (data, "test6a") != 0) + { + fprintf (stderr, "tst_cleanup_6 called with wrong data, got \"%s\"\n", + (char *)data); + cleanup6_retval = 1; + return; + } + + if (error_status != PAM_DATA_REPLACE) + { + fprintf (stderr, "tst_cleanup_6 called with error_status set: %d\n", + error_status); + cleanup6_retval = 1; + return; + } + } + else + { + if (strcmp (data, "test6b") != 0) + { + fprintf (stderr, "tst_cleanup_6 called with wrong data, got \"%s\"\n", + (char *)data); + cleanup6_retval = 1; + return; + } + + if (error_status != 0) + { + fprintf (stderr, "tst_cleanup_6 called with error_status set: %d\n", + error_status); + cleanup6_retval = 1; + return; + } + } + + free (data); +} + +static void +tst_cleanup_7 (pam_handle_t *pamh UNUSED, void *data, int error_status) +{ + cleanup7_was_called = 1; + + if (error_status & PAM_DATA_SILENT) + { + fprintf (stderr, "tst_cleanup_7 called with PAM_DATA_SILENT set\n"); + cleanup7_retval = 1; + return; + } + + if (error_status & PAM_DATA_REPLACE) + { + if (strcmp (data, "test7a") != 0) + { + fprintf (stderr, "tst_cleanup_7 called with wrong data, got \"%s\"\n", + (char *)data); + cleanup7_retval = 1; + return; + } + + if (error_status != PAM_DATA_REPLACE) + { + fprintf (stderr, "tst_cleanup_7 called with error_status set: %d\n", + error_status); + cleanup7_retval = 1; + return; + } + } + else + { + fprintf (stderr, "tst_cleanup_7 called without PAM_DATA_REPLACE set: %d\n", + error_status); + cleanup7_retval = 1; + return; + } + + free (data); +} + +static void +tst_cleanup_7b (pam_handle_t *pamh UNUSED, void *data, int error_status) +{ + cleanup7b_was_called = 1; + + if (strcmp (data, "test7b") != 0) + { + fprintf (stderr, "tst_cleanup_7b called with wrong data, got \"%s\"\n", + (char *)data); + cleanup7b_retval = 1; + return; + } + + free (data); + + if (error_status & PAM_DATA_REPLACE) + { + fprintf (stderr, "tst_cleanup_7b called with PAM_DATA_REPLACE set\n"); + cleanup7b_retval = 1; + return; + } + + if (error_status & PAM_DATA_SILENT) + { + fprintf (stderr, "tst_cleanup_7b called with PAM_DATA_SILENT set\n"); + cleanup7b_retval = 1; + return; + } + + if (error_status != 0) + { + fprintf (stderr, "tst_cleanup_7b called with error_status set: %d\n", + error_status); + cleanup7b_retval = 1; + return; + } +} + +static void +tst_cleanup_8 (pam_handle_t *pamh UNUSED, void *data, int error_status) +{ + cleanup8_was_called = 1; + + if (strcmp (data, "test8") != 0) + { + fprintf (stderr, "tst_cleanup_8 called with wrong data, got \"%s\"\n", + (char *)data); + cleanup8_retval = 1; + return; + } + + free (data); + + if (error_status & PAM_DATA_REPLACE) + { + fprintf (stderr, "tst_cleanup_8 called with PAM_DATA_REPLACE set\n"); + cleanup8_retval = 1; + return; + } + + if (error_status & PAM_DATA_SILENT) + { + fprintf (stderr, "tst_cleanup_8 called with PAM_DATA_SILENT set\n"); + cleanup8_retval = 1; + return; + } + + if (error_status != 987) + { + fprintf (stderr, "tst_cleanup_8 called with wrong error_status set: %d\n", + error_status); + cleanup8_retval = 1; + return; + } +} + +int +main (void) +{ + const char *service = "dummy"; + const char *user = "root"; + struct pam_conv conv; + pam_handle_t *pamh; + void *dataptr; + int retval; + + /* 1: Call with NULL as pam handle */ + dataptr = strdup ("test1"); + retval = pam_set_data (NULL, "tst-pam_set_data-1", dataptr, tst_cleanup); + if (retval == PAM_SUCCESS) + { + fprintf (stderr, "pam_set_data (NULL, ...) returned PAM_SUCCESS\n"); + return 1; + } + free (dataptr); + + /* setup pam handle */ + retval = pam_start (service, user, &conv, &pamh); + if (retval != PAM_SUCCESS) + { + fprintf (stderr, "pam_start (%s, %s, &conv, &pamh) returned %d\n", + service, user, retval); + return 1; + } + + /* 2: check for call from application */ + dataptr = strdup ("test2"); + retval = pam_set_data (pamh, "tst-pam_set_data-2", dataptr, tst_cleanup); + if (retval != PAM_SYSTEM_ERR) + { + fprintf (stderr, + "pam_set_data returned %d when expecting PAM_SYSTEM_ERR\n", + retval); + return 1; + } + free (dataptr); + + + /* 3: check for call from module */ + __PAM_TO_MODULE(pamh); + dataptr = strdup ("test3"); + retval = pam_set_data (pamh, "tst-pam_set_data-3", dataptr, + tst_cleanup_3); + if (retval != PAM_SUCCESS) + { + fprintf (stderr, + "pam_set_data failed: %d\n", + retval); + return 1; + } + + /* 4: check for call with NULL as module_data_name */ + dataptr = strdup ("test4"); + retval = pam_set_data (pamh, NULL, dataptr, tst_cleanup); + if (retval == PAM_SUCCESS) + { + fprintf (stderr, + "pam_set_data with NULL as module_data_name succeded!\n"); + return 1; + } + free (dataptr); + + /* 5: check for call with NULL as cleanup function */ + dataptr = strdup ("test5"); + retval = pam_set_data (pamh, "tst-pam_set_data-5", dataptr, NULL); + if (retval != PAM_SUCCESS) + { + fprintf (stderr, + "pam_set_data with NULL as cleanup function failed: %d\n", + retval); + return 1; + } + free (dataptr); + + /* 6: Overwrite data and check cleanup flags */ + dataptr = strdup ("test6a"); + retval = pam_set_data (pamh, "tst-pam_set_data-6", dataptr, + tst_cleanup_6); + if (retval != PAM_SUCCESS) + { + fprintf (stderr, + "test6: first pam_set_data failed: %d\n", + retval); + return 1; + } + + dataptr = strdup ("test6b"); + retval = pam_set_data (pamh, "tst-pam_set_data-6", dataptr, + tst_cleanup_6); + if (retval != PAM_SUCCESS) + { + fprintf (stderr, + "test6: second pam_set_data failed: %d\n", + retval); + return 1; + } + + /* 7: Overwrite data and cleanup function, check cleanup flags */ + dataptr = strdup ("test7a"); + retval = pam_set_data (pamh, "tst-pam_set_data-7", dataptr, + tst_cleanup_7); + if (retval != PAM_SUCCESS) + { + fprintf (stderr, + "test7: first pam_set_data failed: %d\n", + retval); + return 1; + } + + dataptr = strdup ("test7b"); + retval = pam_set_data (pamh, "tst-pam_set_data-7", dataptr, + tst_cleanup_7b); + if (retval != PAM_SUCCESS) + { + fprintf (stderr, + "test7: second pam_set_data failed: %d\n", + retval); + return 1; + } + + __PAM_TO_APP(pamh); + + /* Close PAM handle and check return codes of cleanup functions */ + retval = pam_end (pamh, 0); + if (retval != PAM_SUCCESS) + { + fprintf (stderr, + "pam_end reported an error: %d\n", + retval); + return 1; + } + + if (cleanup_was_called == 1) + return 1; + + if (cleanup3_was_called == 0) + { + fprintf (stderr, "tst_cleanup_3 was never called!\n"); + return 1; + } + if (cleanup3_retval != 0) + return 1; + + if (cleanup6_was_called == 0) + { + fprintf (stderr, "tst_cleanup_6 was never called!\n"); + return 1; + } + if (cleanup6_retval != 0) + return 1; + + if (cleanup7_was_called == 0) + { + fprintf (stderr, "tst_cleanup_7 was never called!\n"); + return 1; + } + if (cleanup7_retval != 0) + return 1; + + if (cleanup7b_was_called == 0) + { + fprintf (stderr, "tst_cleanup_7b was never called!\n"); + return 1; + } + if (cleanup7b_retval != 0) + return 1; + + /* test if error code is delivered to cleanup function */ + /* setup pam handle */ + retval = pam_start (service, user, &conv, &pamh); + if (retval != PAM_SUCCESS) + { + fprintf (stderr, "pam_start (%s, %s, &conv, &pamh) returned %d\n", + service, user, retval); + return 1; + } + + /* 8: check if cleanup function is called with correct error code */ + __PAM_TO_MODULE(pamh); + dataptr = strdup ("test8"); + retval = pam_set_data (pamh, "tst-pam_set_data-8", dataptr, + tst_cleanup_8); + if (retval != PAM_SUCCESS) + { + fprintf (stderr, + "test8: pam_set_data failed: %d\n", + retval); + return 1; + } + + __PAM_TO_APP(pamh); + + retval = pam_end (pamh, 987); + if (retval != PAM_SUCCESS) + { + fprintf (stderr, + "pam_end reported an error: %d\n", + retval); + return 1; + } + + if (cleanup8_was_called == 0) + { + fprintf (stderr, "tst_cleanup_3 was never called!\n"); + return 1; + } + + if (cleanup8_retval != 0) + return 1; + + return 0; +}