diff options
author | Jakub Hrozek <jakub.hrozek@posteo.se> | 2015-10-29 19:02:27 +0100 |
---|---|---|
committer | Andreas Schneider <asn@samba.org> | 2015-12-10 13:31:19 +0100 |
commit | 6928549dc6da0b059305bc2e4d34f4e83beeb74f (patch) | |
tree | f3e84b458ce8f629b1bb22617937cd2c94774646 | |
parent | b8bfb6ac0f76f9ad5c952a9e36a7a39cf03b11ec (diff) | |
download | pam_wrapper-6928549dc6da0b059305bc2e4d34f4e83beeb74f.tar.gz pam_wrapper-6928549dc6da0b059305bc2e4d34f4e83beeb74f.tar.xz pam_wrapper-6928549dc6da0b059305bc2e4d34f4e83beeb74f.zip |
docs: Add man pages for modules
-rw-r--r-- | doc/CMakeLists.txt | 10 | ||||
-rw-r--r-- | doc/README | 2 | ||||
-rw-r--r-- | doc/pam_get_items.8 | 71 | ||||
-rw-r--r-- | doc/pam_get_items.8.txt | 46 | ||||
-rw-r--r-- | doc/pam_matrix.8 | 127 | ||||
-rw-r--r-- | doc/pam_matrix.8.txt | 80 | ||||
-rw-r--r-- | doc/pam_set_items.8 | 71 | ||||
-rw-r--r-- | doc/pam_set_items.8.txt | 45 | ||||
-rw-r--r-- | doc/pam_wrapper.1 | 57 | ||||
-rw-r--r-- | doc/pam_wrapper.1.txt | 52 | ||||
-rw-r--r-- | src/pam_wrapper.c | 75 | ||||
-rw-r--r-- | tests/test_pam_wrapper.c | 2 |
12 files changed, 579 insertions, 59 deletions
diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt index ef9effb..3d9cc11 100644 --- a/doc/CMakeLists.txt +++ b/doc/CMakeLists.txt @@ -2,3 +2,13 @@ install(FILES pam_wrapper.1 DESTINATION ${MAN_INSTALL_DIR}/man1) + +install(FILES + pam_get_items.8 + DESTINATION + ${MAN_INSTALL_DIR}/man8) + +install(FILES + pam_set_items.8 + DESTINATION + ${MAN_INSTALL_DIR}/man8) @@ -1,3 +1,5 @@ The manpage is written with asciidoc. To generate the manpage use: a2x --doctype manpage --format manpage doc/pam_wrapper.1.txt + +for m in doc/pam_*.[0-9].txt; do a2x --doctype manpage --format manpage $m; done diff --git a/doc/pam_get_items.8 b/doc/pam_get_items.8 new file mode 100644 index 0000000..8ab6e82 --- /dev/null +++ b/doc/pam_get_items.8 @@ -0,0 +1,71 @@ +'\" t +.\" Title: pam_get_items +.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] +.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/> +.\" Date: 2015-11-04 +.\" Manual: \ \& +.\" Source: \ \& +.\" Language: English +.\" +.TH "PAM_GET_ITEMS" "8" "2015\-11\-04" "\ \&" "\ \&" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +pam_get_items \- A PAM test module to retrieve module\-specific PAM items +.SH "SYNOPSIS" +.sp +pam_get_items\&.so +.SH "DESCRIPTION" +.sp +PAM modules store data in PAM \fIitems\fR\&. These items are only accessible from module context, not application context as they might include private data (PAM_AUTHTOK normally contains the password)\&. But when testing PAM modules, it\(cqs often nice to make sure a PAM module under test sets items for the next module the way it\(cqs supposed to\&. The pam_get_items module makes this possible by exporting all PAM items as environment variables using pam_putenv\&. The environment variable name is the same as the constant name of the PAM item\&. +.SH "OPTIONS" +.sp +None +.SH "MODULE TYPES PROVIDED" +.sp +All module types (\fBaccount\fR, \fBauth\fR, \fBpassword\fR and \fBsession\fR) are provided\&. +.SH "EXAMPLE" +.sp +Consider an example that tests that pam_unix puts the password it reads onto PAM stack\&. The test service file would contain: +.sp +.if n \{\ +.RS 4 +.\} +.nf +auth required pam_unix\&.so +auth required pam_get_items\&.so +.fi +.if n \{\ +.RE +.\} +.sp +Then the test would run the PAM conversation and afterwards call: +.sp +.if n \{\ +.RS 4 +.\} +.nf +pam_getenv(pamh, "PAM_AUTHTOK"); +.fi +.if n \{\ +.RE +.\} +.sp +To retrieve the password\&. diff --git a/doc/pam_get_items.8.txt b/doc/pam_get_items.8.txt new file mode 100644 index 0000000..0d280f3 --- /dev/null +++ b/doc/pam_get_items.8.txt @@ -0,0 +1,46 @@ +pam_get_items(8) +=============== +:revdate: 2015-11-04 + +NAME +---- + +pam_get_items - A PAM test module to retrieve module-specific PAM items + +SYNOPSIS +-------- +pam_get_items.so + +DESCRIPTION +----------- +PAM modules store data in PAM _items_. These items are only accessible from +module context, not application context as they might include private data +(PAM_AUTHTOK normally contains the password). But when testing PAM modules, +it's often nice to make sure a PAM module under test sets items for the next +module the way it's supposed to. The pam_get_items module makes this possible +by exporting all PAM items as environment variables using pam_putenv. The +environment variable name is the same as the constant name of the PAM item. + +OPTIONS +------- +None + +MODULE TYPES PROVIDED +--------------------- +All module types (*account*, *auth*, *password* and *session*) are provided. + +EXAMPLE +------- +Consider an example that tests that pam_unix puts the password it reads +onto PAM stack. The test service file would contain: + +[source,bash] +auth required pam_unix.so +auth required pam_get_items.so + +Then the test would run the PAM conversation and afterwards call: + +[source,c] +pam_getenv(pamh, "PAM_AUTHTOK"); + +To retrieve the password. diff --git a/doc/pam_matrix.8 b/doc/pam_matrix.8 new file mode 100644 index 0000000..80d5190 --- /dev/null +++ b/doc/pam_matrix.8 @@ -0,0 +1,127 @@ +'\" t +.\" Title: pam_matrix +.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] +.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/> +.\" Date: 2015-11-04 +.\" Manual: \ \& +.\" Source: \ \& +.\" Language: English +.\" +.TH "PAM_MATRIX" "8" "2015\-11\-04" "\ \&" "\ \&" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +pam_matrix \- A PAM test module to retrieve module\-specific PAM items +.SH "SYNOPSIS" +.sp +pam_matrix\&.so [\&...] +.SH "DESCRIPTION" +.sp +Testing PAM application often requires to set up an authentication backend with as little effort as possible\&. The \fBpam_matrix\fR module allows to authenticate against a key\-value text file, provided by an option or with an environment variable\&. +.SH "IMPORTANT" +.sp +pam_matrix is a \fBtest tool\fR\&. It should be considered completely insecure and never used outside test environments! As you\(cqll see when reading description of the options and actions, many of them don\(cqt make any sense in the real world and were added just to make tests possible\&. +.SH "PASSWORD DATABASE" +.sp +The pam_matrix module authenticates user against a plain\-text CSV file\&. The format of the file is as follows: +.sp +.if n \{\ +.RS 4 +.\} +.nf +username:password:allowed_service +.fi +.if n \{\ +.RE +.\} +.sp +Example: User bob allowed to authenticate with the service sshd +.sp +.if n \{\ +.RS 4 +.\} +.nf +bob:secret:sshd +.fi +.if n \{\ +.RE +.\} +.SH "OPTIONS" +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +.sp -1 +.IP \(bu 2.3 +.\} +\fBpassdb=/path/to/file\fR +\- the patch to the password database\&. If the database is not provided with this module option, pam_matrix\&.so reads the PAM_MATRIX_PASSWD environment variable and tries to load the file from there\&. If that fails as well, PAM_AUTHINFO_UNAVAIL is returned\&. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +.sp -1 +.IP \(bu 2.3 +.\} +\fBecho\fR +\- if this option is provided, pam_matrix\&.so will ask for password using PAM_PROMPT_ECHO_ON, that is, the password will be echoed back to user\&. This option was added to make it possible to test conversation functions better\&. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +.sp -1 +.IP \(bu 2.3 +.\} +\fBverbose\fR +\- if this option is provided, pam_matrix\&.so will display a PAM_TEXT_INFO message when authentication succeeds and a PAM_ERROR_MSG when authentication fails\&. This option was added to make it possible to test conversation functions better\&. +.RE +.SH "MODULE TYPES PROVIDED" +.sp +All module types (\fBaccount\fR, \fBauth\fR, \fBpassword\fR and \fBsession\fR) are supported\&. +.sp +The \fBauth\fR module searches for the user in the passdb file and compares the provided password with the one in the passdb file\&. +.sp +The \fBpassword\fR module is able to update the password in the passdb file\&. +.sp +The \fBaccess\fR module compares the service name the PAM conversation was invoked with the allowed service for the user as set in the passdb file\&. +.sp +The \fBsession\fR module sets the HOMEDIR PAM environment variable to "/home/%u" where %u stands for the user who opens the session\&. The variable is unset on session close\&. +.SH "EXAMPLE" +.sp +.if n \{\ +.RS 4 +.\} +.nf +auth required pam_matrix\&.so passdb=/tmp/passdb verbose +account required pam_matrix\&.so passdb=/tmp/passdb verbose +password required pam_matrix\&.so passdb=/tmp/passdb verbose +session required pam_matrix\&.so passdb=/tmp/passdb verbose +.fi +.if n \{\ +.RE +.\} diff --git a/doc/pam_matrix.8.txt b/doc/pam_matrix.8.txt new file mode 100644 index 0000000..fb54f05 --- /dev/null +++ b/doc/pam_matrix.8.txt @@ -0,0 +1,80 @@ +pam_matrix(8) +=============== +:revdate: 2015-11-04 + +NAME +---- + +pam_matrix - A PAM test module to retrieve module-specific PAM items + +SYNOPSIS +-------- +pam_matrix.so [...] + +DESCRIPTION +----------- +Testing PAM application often requires to set up an authentication backend with +as little effort as possible. The *pam_matrix* module allows to authenticate +against a key-value text file, provided by an option or with an environment +variable. + +IMPORTANT +--------- +pam_matrix is a *test tool*. It should be considered completely insecure +and never used outside test environments! As you'll see when reading +description of the options and actions, many of them don't make any sense +in the real world and were added just to make tests possible. + +PASSWORD DATABASE +----------------- +The pam_matrix module authenticates user against a plain-text CSV file. The +format of the file is as follows: + +[source,bash] +username:password:allowed_service + +Example: User bob allowed to authenticate with the service sshd + +[source,bash] +bob:secret:sshd + +OPTIONS +------- +* *passdb=/path/to/file* - the patch to the password database. If the +database is not provided with this module option, pam_matrix.so reads the +PAM_MATRIX_PASSWD environment variable and tries to load the file from +there. If that fails as well, PAM_AUTHINFO_UNAVAIL is returned. + +* *echo* - if this option is provided, pam_matrix.so will ask for password +using PAM_PROMPT_ECHO_ON, that is, the password will be echoed back to user. +This option was added to make it possible to test conversation functions +better. + +* *verbose* - if this option is provided, pam_matrix.so will display a +PAM_TEXT_INFO message when authentication succeeds and a PAM_ERROR_MSG +when authentication fails. This option was added to make it possible to +test conversation functions better. + +MODULE TYPES PROVIDED +--------------------- +All module types (*account*, *auth*, *password* and *session*) are supported. + +The *auth* module searches for the user in the passdb file and compares the +provided password with the one in the passdb file. + +The *password* module is able to update the password in the passdb file. + +The *access* module compares the service name the PAM conversation was invoked +with the allowed service for the user as set in the passdb file. + +The *session* module sets the HOMEDIR PAM environment variable to "/home/%u" +where %u stands for the user who opens the session. The variable is unset +on session close. + +EXAMPLE +------- +[source,bash] +auth required pam_matrix.so passdb=/tmp/passdb verbose +account required pam_matrix.so passdb=/tmp/passdb verbose +password required pam_matrix.so passdb=/tmp/passdb verbose +session required pam_matrix.so passdb=/tmp/passdb verbose diff --git a/doc/pam_set_items.8 b/doc/pam_set_items.8 new file mode 100644 index 0000000..fdb80b7 --- /dev/null +++ b/doc/pam_set_items.8 @@ -0,0 +1,71 @@ +'\" t +.\" Title: pam_set_items +.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] +.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/> +.\" Date: 2015-11-04 +.\" Manual: \ \& +.\" Source: \ \& +.\" Language: English +.\" +.TH "PAM_SET_ITEMS" "8" "2015\-11\-04" "\ \&" "\ \&" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +pam_set_items \- A PAM test module to set module\-specific PAM items +.SH "SYNOPSIS" +.sp +pam_set_items\&.so +.SH "DESCRIPTION" +.sp +PAM modules store data in PAM \fIitems\fR\&. These items are only accessible from module context, not application context as they might include private data (PAM_AUTHTOK normally contains the password)\&. But when testing PAM modules, it\(cqs often nice to make sure a PAM module under test can retrieve data from the stack\&. The pam_set_items module makes this possible by reading environment variables and setting them as PAM items\&. +.SH "OPTIONS" +.sp +None +.SH "MODULE TYPES PROVIDED" +.sp +All module types (\fBaccount\fR, \fBauth\fR, \fBpassword\fR and \fBsession\fR) are provided\&. +.SH "EXAMPLE" +.sp +Consider an example that tests that pam_unix is able to read a provided password and doesn\(cqt query on its own\&. The test service file would contain: +.sp +.if n \{\ +.RS 4 +.\} +.nf +auth required pam_set_items\&.so +auth required pam_unix\&.so +.fi +.if n \{\ +.RE +.\} +.sp +Then the test would put the item to the test environment with: +.sp +.if n \{\ +.RS 4 +.\} +.nf +setenv("PAM_AUTHTOK", "secret"); +.fi +.if n \{\ +.RE +.\} +.sp +Then run the PAM conversation\&. diff --git a/doc/pam_set_items.8.txt b/doc/pam_set_items.8.txt new file mode 100644 index 0000000..60d5e50 --- /dev/null +++ b/doc/pam_set_items.8.txt @@ -0,0 +1,45 @@ +pam_set_items(8) +=============== +:revdate: 2015-11-04 + +NAME +---- + +pam_set_items - A PAM test module to set module-specific PAM items + +SYNOPSIS +-------- +pam_set_items.so + +DESCRIPTION +----------- +PAM modules store data in PAM _items_. These items are only accessible from +module context, not application context as they might include private data +(PAM_AUTHTOK normally contains the password). But when testing PAM modules, +it's often nice to make sure a PAM module under test can retrieve data +from the stack. The pam_set_items module makes this possible by reading +environment variables and setting them as PAM items. + +OPTIONS +------- +None + +MODULE TYPES PROVIDED +--------------------- +All module types (*account*, *auth*, *password* and *session*) are provided. + +EXAMPLE +------- +Consider an example that tests that pam_unix is able to read a provided password +and doesn't query on its own. The test service file would contain: + +[source,bash] +auth required pam_set_items.so +auth required pam_unix.so + +Then the test would put the item to the test environment with: + +[source,c] +setenv("PAM_AUTHTOK", "secret"); + +Then run the PAM conversation. diff --git a/doc/pam_wrapper.1 b/doc/pam_wrapper.1 index 2e73e5f..0d737a9 100644 --- a/doc/pam_wrapper.1 +++ b/doc/pam_wrapper.1 @@ -2,12 +2,12 @@ .\" Title: pam_wrapper .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/> -.\" Date: 09/30/2015 +.\" Date: 2015-11-04 .\" Manual: \ \& .\" Source: \ \& .\" Language: English .\" -.TH "PAM_WRAPPER" "1" "09/30/2015" "\ \&" "\ \&" +.TH "PAM_WRAPPER" "1" "2015\-11\-04" "\ \&" "\ \&" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- @@ -28,29 +28,29 @@ .\" * MAIN CONTENT STARTS HERE * .\" ----------------------------------------------------------------- .SH "NAME" -pam_wrapper \- A wrapper test PAM and PAM Modules +pam_wrapper \- A preloadable wrapper to test PAM applications and PAM Modules .SH "SYNOPSIS" .sp -LD_PRELOAD=libpam_wrapper\&.so PAM_WRAPPER=1 PAM_WRAPPER_CONFIGDIR=/path_to_config \fB\&./myapplication\fR +LD_PRELOAD=libpam_wrapper\&.so PAM_WRAPPER=1 PAM_WRAPPER_SERVICE_DIR=/path_to_config \fB\&./myapplication\fR .SH "DESCRIPTION" .sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -Allows pam testing -.RE +This tool allows you to either test your PAM application or module\&. For testing PAM applications we have written a simple PAM module called pam_matrix (see below)\&. If you plan to test a PAM module you can use the pamtest library we have implemented\&. It simplifies testing of modules\&. You can be combine it with the cmocka unit testing framework or you can use the provided Python bindings to write tests for your module in Python\&. .SH "ENVIRONMENT VARIABLES" +.sp +pam_wrapper is activated and controlled by environment variables\&. You can set the following variables: .PP \fBPAM_WRAPPER\fR .RS 4 -If you load the pam_wrapper and enable it with setting PAM_WRAPPER=1 all setpam and setgid will work, even as a normal user\&. +If you load the pam_wrapper and enable it with setting PAM_WRAPPER=1 all PAM calls will be wrapped so you are able to specify a directory with the service files pam_wrapper should be using\&. .RE .PP +\fBPAM_WRAPPER_SERVICE_DIR\fR +.RS 4 +The directory to read PAM service files from\&. +.RE +.sp +If you want to use pam_matrix (see below) or want to test your own PAM module you need to specify the absolute path to your module in the service files\&. +.PP \fBPAM_WRAPPER_DEBUGLEVEL\fR .RS 4 If you need to see what is going on in pam_wrapper itself or try to find a bug, you can enable logging support in pam_wrapper if you built it with debug symbols\&. @@ -99,6 +99,31 @@ If you need to see what is going on in pam_wrapper itself or try to find a bug, 3 = TRACE .RE .RE +.PP +\fBPAM_WRAPPER_KEEP_DIR\fR +.RS 4 +If this option is set to 1, then pam_wrapper won\(cqt delete its temporary directories\&. Mostly useful for pam_wrapper development\&. +.RE .SH "EXAMPLE" .sp -An example \&... +A service file for pam_wrapper should look like this: +.sp +.if n \{\ +.RS 4 +.\} +.nf +auth required /usr/lib/pam_wrapper/pam_matrix\&.so passdb=/path/to/pdb +account required /usr/lib/pam_wrapper/pam_matrix\&.so passdb=/path/to/pdb +password required /usr/lib/pam_wrapper/pam_matrix\&.so passdb=/path/to/pdb +session required /usr/lib/pam_wrapper/pam_matrix\&.so passdb=/path/to/pdb +.fi +.if n \{\ +.RE +.\} +.sp +The name of the file should represent the service name used by your PAM application\&. +.sp +LD_PRELOAD=\&./libpam_wrapper\&.so PAM_WRAPPER=1 PAM_WRAPPER_SERVICE_DIR=pam_services/ \&./my_pam_app +.SH "PAM_MATRIX" +.sp +We offer a module to make testing of PAM applications easier\&. You find more information in the pam_matrix(8) manpage\&. diff --git a/doc/pam_wrapper.1.txt b/doc/pam_wrapper.1.txt index 699b854..b565931 100644 --- a/doc/pam_wrapper.1.txt +++ b/doc/pam_wrapper.1.txt @@ -1,28 +1,45 @@ pam_wrapper(1) ============== +:revdate: 2015-11-04 NAME ---- -pam_wrapper - A wrapper test PAM and PAM Modules +pam_wrapper - A preloadable wrapper to test PAM applications and PAM Modules SYNOPSIS -------- -LD_PRELOAD=libpam_wrapper.so PAM_WRAPPER=1 PAM_WRAPPER_CONFIGDIR=/path_to_config *./myapplication* +LD_PRELOAD=libpam_wrapper.so PAM_WRAPPER=1 PAM_WRAPPER_CONFDIR=/path_to_config *./myapplication* DESCRIPTION ----------- -- Allows pam testing +This tool allows you to either test your PAM application or module. For testing +PAM applications we have written a simple PAM module called pam_matrix +(see below). If you plan to test a PAM module you can use the pamtest library +we have implemented. It simplifies testing of modules. You can be combine it +with the cmocka unit testing framework or you can use the provided Python +bindings to write tests for your module in Python. ENVIRONMENT VARIABLES --------------------- +pam_wrapper is activated and controlled by environment variables. You can set +the following variables: + *PAM_WRAPPER*:: -If you load the pam_wrapper and enable it with setting PAM_WRAPPER=1 all libpam -calls will be directed through a wrapper copy of libpam. +If you load the pam_wrapper and enable it with setting PAM_WRAPPER=1 all PAM +calls will be wrapped so you are able to specify a directory with the service +files pam_wrapper should be using. + +*PAM_WRAPPER_CONFDIR*:: + +The directory to read PAM service files from. + +If you want to use pam_matrix (see below) or want to test your own PAM module +you need to specify the absolute path to your module in the service files. *PAM_WRAPPER_DEBUGLEVEL*:: @@ -35,7 +52,30 @@ debug symbols. - 2 = DEBUG - 3 = TRACE +*PAM_WRAPPER_KEEP_DIR*:: + +If this option is set to 1, then pam_wrapper won't delete its temporary +directories. Mostly useful for pam_wrapper development. + EXAMPLE ------- -An example ... +A service file for pam_wrapper should look like this: + +-------------------------------------- +auth required /usr/lib/pam_wrapper/pam_matrix.so passdb=/path/to/pdb +account required /usr/lib/pam_wrapper/pam_matrix.so passdb=/path/to/pdb +password required /usr/lib/pam_wrapper/pam_matrix.so passdb=/path/to/pdb +session required /usr/lib/pam_wrapper/pam_matrix.so passdb=/path/to/pdb +-------------------------------------- + +The name of the file should represent the service name used by your PAM +application. + +LD_PRELOAD=./libpam_wrapper.so PAM_WRAPPER=1 PAM_WRAPPER_SERVICE_DIR=pam_services/ ./my_pam_app + +PAM_MATRIX +---------- + +We offer a module to make testing of PAM applications easier. You find more +information in the pam_matrix(8) manpage. diff --git a/src/pam_wrapper.c b/src/pam_wrapper.c index abe6bbf..59119ab 100644 --- a/src/pam_wrapper.c +++ b/src/pam_wrapper.c @@ -239,7 +239,7 @@ struct pwrap { bool enabled; bool initialised; char *config_dir; - char *pam_library; + char *libpam_so; }; static struct pwrap pwrap; @@ -273,19 +273,11 @@ static void *pwrap_load_lib_handle(enum pwrap_lib lib) case PWRAP_LIBPAM: handle = pwrap.libpam.handle; if (handle == NULL) { - char libpam_path[PATH_MAX]; - - snprintf(libpam_path, - sizeof(libpam_path), - "%s/%s", - pwrap.config_dir, LIBPAM_NAME); - - handle = dlopen(libpam_path, flags); + handle = dlopen(pwrap.libpam_so, flags); if (handle != NULL) { pwrap.libpam.handle = handle; break; } - } break; } @@ -654,7 +646,7 @@ static void pwrap_init(void) uint32_t i; int rc; char pam_library[128] = { 0 }; - char pam_path[1024] = { 0 }; + char libpam_path[1024] = { 0 }; ssize_t ret; if (!pam_wrapper_enabled()) { @@ -713,25 +705,38 @@ static void pwrap_init(void) tmp_config_dir, strerror(errno)); } - snprintf(pam_path, - sizeof(pam_path), - "%s/%s", + /* create lib subdirectory */ + snprintf(libpam_path, + sizeof(libpam_path), + "%s/lib", + pwrap.config_dir); + + rc = mkdir(libpam_path, 0755); + if (rc != 0) { + PWRAP_LOG(PWRAP_LOG_ERROR, + "Failed to create pam_wrapper config dir: %s - %s", + tmp_config_dir, strerror(errno)); + } + + snprintf(libpam_path, + sizeof(libpam_path), + "%s/lib/%s", pwrap.config_dir, LIBPAM_NAME); - pwrap.pam_library = strdup(pam_path); - if (pwrap.pam_library == NULL) { + pwrap.libpam_so = strdup(libpam_path); + if (pwrap.libpam_so == NULL) { PWRAP_LOG(PWRAP_LOG_ERROR, "No memory"); exit(1); } /* copy libpam.so.0 */ - snprintf(pam_path, sizeof(pam_path), "%s", PAM_LIBRARY); + snprintf(libpam_path, sizeof(libpam_path), "%s", PAM_LIBRARY); PWRAP_LOG(PWRAP_LOG_TRACE, "PAM path: %s", - pam_path); + libpam_path); - ret = readlink(pam_path, pam_library, sizeof(pam_library)); + ret = readlink(libpam_path, pam_library, sizeof(pam_library)); PWRAP_LOG(PWRAP_LOG_TRACE, "PAM library: %s", pam_library); @@ -741,33 +746,33 @@ static void pwrap_init(void) } if (pam_library[0] == '/') { - snprintf(pam_path, - sizeof(pam_path), + snprintf(libpam_path, + sizeof(libpam_path), "%s", pam_library); } else { - char pam_path_cp[sizeof(pam_path)]; + char libpam_path_cp[sizeof(libpam_path)]; char *dname; - strncpy(pam_path_cp, pam_path, sizeof(pam_path_cp)); + strncpy(libpam_path_cp, libpam_path, sizeof(libpam_path_cp)); - dname = dirname(pam_path_cp); + dname = dirname(libpam_path_cp); if (dname == NULL) { PWRAP_LOG(PWRAP_LOG_ERROR, - "No directory component in %s", pam_path); + "No directory component in %s", libpam_path); exit(1); } - snprintf(pam_path, - sizeof(pam_path), + snprintf(libpam_path, + sizeof(libpam_path), "%s/%s", dname, pam_library); } - PWRAP_LOG(PWRAP_LOG_TRACE, "Reconstructed PAM path: %s", pam_path); + PWRAP_LOG(PWRAP_LOG_TRACE, "Reconstructed PAM path: %s", libpam_path); - PWRAP_LOG(PWRAP_LOG_DEBUG, "Copy %s to %s", pam_path, pwrap.pam_library); - rc = p_copy(pam_path, pwrap.pam_library, pwrap.config_dir, 0644); + PWRAP_LOG(PWRAP_LOG_DEBUG, "Copy %s to %s", libpam_path, pwrap.libpam_so); + rc = p_copy(libpam_path, pwrap.libpam_so, pwrap.config_dir, 0644); if (rc != 0) { PWRAP_LOG(PWRAP_LOG_ERROR, "Failed to copy %s - error: %s", @@ -776,8 +781,6 @@ static void pwrap_init(void) exit(1); } - /* modify libpam.so */ - pwrap.initialised = true; env = getenv("PAM_WRAPPER_CONFDIR"); @@ -792,7 +795,7 @@ static void pwrap_init(void) exit(1); } - setenv("PWRAP_TEST_CONF_DIR", pwrap.config_dir, 1); + setenv("PAM_WRAPPER_SERVICE_DIR", pwrap.config_dir, 1); PWRAP_LOG(PWRAP_LOG_DEBUG, "Successfully initialized pam_wrapper"); } @@ -1320,9 +1323,9 @@ void pwrap_destructor(void) dlclose(pwrap.libpam.handle); } - if (pwrap.pam_library != NULL) { - free(pwrap.pam_library); - pwrap.pam_library = NULL; + if (pwrap.libpam_so != NULL) { + free(pwrap.libpam_so); + pwrap.libpam_so = NULL; } if (!pwrap.initialised) { diff --git a/tests/test_pam_wrapper.c b/tests/test_pam_wrapper.c index 2c2c4ee..1c78476 100644 --- a/tests/test_pam_wrapper.c +++ b/tests/test_pam_wrapper.c @@ -176,7 +176,7 @@ static void test_env(void **state) (void) state; /* unused */ - v = getenv("PWRAP_TEST_CONF_DIR"); + v = getenv("PAM_WRAPPER_SERVICE_DIR"); assert_non_null(v); ret = stat(v, &sb); |