This is an old revision of the document!
Table of Contents
PAM Authentication Backend
I wanted to authenticate users without have a separate set of passwords. I found this authentication backend, but it doesn't work with the latest version of DokuWiki. I therefore set about writing my own authentication backend, which I will post here. I haven't tested it extensively, but it seems to work for me
Operation
The backend extends the auth_plain backend and overrides the checkPass()
function to authenticate against PAM instead of the text file. The text file is still used to store users' names, email addresses and groups. Users must exist in both the text file (this can be done with the User Manager) and in PAM before they can login. A random password is stored in the text file, but this is simply ignored.
PHP PAM Module
The backend requires the PHP PAM module to be installed. If your PHP configuration does not allow dynamic loading of modules (enable_dl = Off
) then you need to load the extension by adding extension=pam.so
to your php.ini
. Make sure you follow the instructions when installing the PAM module – you must configure PAM with a php
service.
Ubuntu
Ubuntu has this module available in a package. To install it and setup PAM simply run the following commands:
sudo aptitude install php5-auth-pam sudo cp /usr/share/doc/php5-auth-pam/examples/php /etc/pam.d/php
Remember to restart your webserver.
Install pam.class.php
Save the following file as inc/auth/pam.class.php
.
<?php /** * PAM authentication backend * @author Michael Gorven <michael003+dokuwiki@gmail.com> * @license GPL2 http://www.gnu.org/licenses/gpl.html * @version 0.2 * @date March 2008 */ # This class requires the PHP PAM module # The Ubuntu package renames it to "pam_auth", so we check both if ( !extension_loaded('pam') && !extension_loaded('pam_auth') ) if ( !dl('pam.so') && !dl('pam_auth.so') ) msg( "PHP PAM module cannot be loaded", -1 ); define('DOKU_AUTH', dirname(__FILE__)); require_once(DOKU_AUTH.'/plain.class.php'); class auth_pam extends auth_plain { /** * Constructor * * Calls the auth_plain constructor which sets the backend's capabilities. * The change password capability is then removed since we can't change * passwords through PAM without knowing the current password. * */ function auth_pam() { // Call parent constructor if (method_exists($this, 'auth_plain')) parent::auth_plain(); // Remove change password capability $this->cando['modPass'] = false; } /** * Checks the provided username and password using PAM. * * @param string $user Username * @param string $pass Password * @return boolean True if authentication is successful */ function checkPass( $user, $pass ) { // Check that user exists if ( parent::getUserData($user) === false ) return false; // Check password else if( pam_auth( $user, $pass, &$error ) ) return true; // Authentication failed else return false; } /** * Creates a new user. * * Uses the createUser() method in auth_plain to actually add the user. * This only adds the user to the list of DokuWiki users -- they must * separately be added to PAM and assigned a password. * * @param string $user Username * @param string $pass Password (will be blank) * @param string $name Full name * @param string $mail Email address * @param string $grps List of groups * @return bool False if user already exists, null if error occurred, true if successful */ function createUser($user,$pwd,$name,$mail,$grps=null) { // createUser() returns the password if successful. We therefore need to // set it to something non-empty otherwise it gets treated as false return parent::createUser( $user, time(), $name, $mail, $grps ); } }
I'm encountering warnings in my Apache logs: “PHP Warning: Call-time pass-by-reference has been deprecated; If you would like to pass it by reference, modify the declaration of pam_auth(). If you would like to enable call-time pass-by-reference, you can set allow_call_time_pass_reference to true in your INI file.”
I simply removed the “&” ampersand in front of the $error parameter in the pam_auth() function call. This seems to work…with no negative repercussions (true?). The warnings no longer appear (as expected with this change).
— poonh [at] mcmaster [dot] ca 2008-Apr-01 03:00 EDT
Patch User Manager
You then need to fix (what I think is) a bug in the User Manager. It won't create a user if no password is specified, but if the authentication backend cannot set passwords then the password box is disabled! The following patch makes the User Manager ignore empty passwords if the authentication backend can't change passwords. Save this in a file called admin.php.diff
in your home directory, and then run patch -p1 < ~/admin.php.diff
in lib/plugins/usermanager
.
--- admin.php.orig 2008-03-13 14:48:57.000000000 +0200 +++ admin.php 2008-03-13 14:57:01.000000000 +0200 @@ -339,7 +339,8 @@ list($user,$pass,$name,$mail,$grps) = $this->_retrieveUser(); if (empty($user)) return false; - if (empty($pass) || empty($name) || empty($mail)){ + // PATCH: Don't fail on empty password if auth backend can't change passwords + if ( (empty($pass)&&$this->_auth->canDo('modPass')) || empty($name) || empty($mail)){ msg($this->lang['add_fail'], -1); return false; }
Configure DokuWiki
You then need to configure DokuWiki to use this authentication backend. Add the following line to local.php
:
$conf['authtype'] = 'pam';
If you want to prevent users from registering themselves, add the following line as well:
$conf['disableactions'] = 'register';
Applicable Version(s)?
I've attempted to duplicate this setup using DokuWiki versions 2008-05-05 and 2007-06-26b on a SAMP stack (Solaris, Apache, MySQL, & PHP provided by CoolStack). However, I'm unsuccessful. Here are the versions I'm using;
- Solaris 10 6/06 (Update 2)
- Apache 2.2.3
- PHP 5.2.0 (cli) (built: Feb 16 2007 08:19:43)
- MySQL 5.0.33-standard
I've added the account that Apache is using to the group that can access /etc/shadow and /etc/passwd, and I've also added the following to /etc/pam.conf
php auth requisite /usr/lib/security/pam_authtok_get.so.1 php auth required /usr/lib/security/pam_unix_auth.so.1 php account required /usr/lib/security/pam_unix_account.so.1
So far I've been able to break 'plain' authentication when attempting 'pam', but I've had no luck in getting it to work. Has anyone had any recent success with this PAM method?
— Eric Xeleema 2008/07/08 04:20