Extension:PwAuthPlugin

From MediaWiki.org

Jump to: navigation, search
Manual on MediaWiki Extensions
List of MediaWiki Extensions
PwAuthPlugin

Release status: unknown

Implementation User identity
Description This extension allows you to authenticate wiki users using your systems password database.
Author(s) Nicholas J. Humfrey
Version 1.0
Download see below

PwAuthPlugin allows you to authenticate wiki users using your systems password database. It uses the pwauth program to perform the authentication, which is available from: http://www.unixpapa.com/pwauth/

Users Real Names and email addresses are automatically added to the wiki database.

Contents

[edit] Download the Extension

The code for the extension is at the bottom of this page. Go ahead and place that in a file in the extensions folder called PwAuthPlugin.php.

[edit] Extension Configuration

Place the following code into the LocalSettings.php file:

require_once("./extensions/PwAuthPlugin.php");
$wgAuth = new PwAuthPlugin();
 
$wgGroupPermissions['*']['createaccount']   = false;
$wgGroupPermissions['*']['read']            = true;
$wgGroupPermissions['*']['edit']            = false;
$wgGroupPermissions['*']['createpage']      = false;
$wgGroupPermissions['*']['createtalk']      = false;
 
$wgShowIPinHeader = false; # For non-logged in users


[edit] Extension Code

<?php
 
/**
 * Version 1.0
 *
 * Authentication Plugin for pwauth
 * Derived from AuthPlugin.php
 *
 * Much of the commenting comes straight from AuthPlugin.php
 *
 * Copyright 2006 Nicholas J. Humfrey
 * Released under the GNU General Public License
 *
 * pwauth is available from http://www.unixpapa.com/pwauth/
 *
 * LocalSettings configuration:
 *  require_once("./extensions/PwAuthPlugin.php");
 *  $wgAuth = new PwAuthPlugin();
 *
 *
 */
 
require_once('AuthPlugin.php');
 
 
$pwauth_email_domain = "";
$pwauth_bin_path = "/usr/local/libexec/pwauth";
 
 
error_reporting(E_ALL); // Debug
 
 
// First check if class has already been defined.
if (!class_exists('AuthPlugin')) {
 
        /**
         * Auth Plugin
         *
         */
        require_once './includes/AuthPlugin.php';
 
} // End: if (!class_exists('AuthPlugin')) {
 
 
 
 
class PwAuthPlugin extends AuthPlugin {
 
        /**
         * Check whether there exists a user account with the given name.
         * The name will be normalized to MediaWiki's requirements, so
         * you might need to munge it (for instance, for lowercase initial
         * letters).
         *
         * @param string $username
         * @return bool
         * @access public
         */
        function userExists( $username ) {
                $user = posix_getpwnam( strtolower($username) );
                return is_array($user);
        }
 
        /**
         * Check if a username+password pair is a valid login.
         * The name will be normalized to MediaWiki's requirements, so
         * you might need to munge it (for instance, for lowercase initial
         * letters).
         *
         * @param string $username
         * @param string $password
         * @return bool
         * @access public
         */
        function authenticate( $username, $password ) {
                global $pwauth_bin_path;
 
                $username = strtolower( $username );
 
                $handle = popen($pwauth_bin_path, 'w');
                if ($handle === FALSE) {
                        error_log("Error opening pipe to pwauth");
                        return false;
                }
 
                if (fwrite($handle, "$username\n$password\n") === FALSE) {
                        error_log("Error writing to pwauth pipe");
                        return false;
                }
 
                # Is the password valid?
                $result = pclose( $handle );
                if ($result==0) return TRUE;
 
                #0  -  Login OK.
                #1  -  Nonexistant login or (for some configurations) incorrect password.
                #2  -  Incorrect password (for some configurations).
                #3  -  Uid number is below MIN_UNIX_UID value configured in config.h.
                #4  -  Login ID has expired.
                #5  -  Login's password has expired.
                #6  -  Logins to system have been turned off (usually by /etc/nologin file).
                #7  -  Limit on number of bad logins exceeded.
                #50 -  pwauth was not run with real uid SERVER_UID.  If you get this
                #      this error code, you probably have SERVER_UID set incorrectly
                #      in pwauth's config.h file.
                #51 -  pwauth was not given a login & password to check.  The means
                #      the passing of data from mod_auth_external to pwauth is messed
                #      up.  Most likely one is trying to pass data via environment
                #      variables, while the other is trying to pass data via a pipe.
                #52 -  one of several possible internal errors occured.
                error_log("pwauth returned $result for username $username");
 
                return false;
        }
 
        /**
         * Modify options in the login template.
         *
         * @param UserLoginTemplate $template
         * @access public
         */
        function modifyUITemplate( &$template ) {
                $template->set('usedomain', false );
                $template->set('useemail', false);     // Disable the mail new password box.
                $template->set('create', false);       // Remove option to create new accounts from the wiki.
        }
 
        /**
         * Check to see if the specific domain is a valid domain.
         *
         * @param string $domain
         * @return bool
         * @access public
         */
        function validDomain( $domain ) {
                # We ignore domains, so erm, yes?
                return true;
        }
 
        /**
         * When a user logs in, optionally fill in preferences and such.
         * For instance, you might pull the email address or real name from the
         * external user database.
         *
         * The User object is passed by reference so it can be modified; don't
         * forget the & on your function declaration.
         *
         * @param User $user
         * @access public
         */
        function updateUser( &$user ) {
                global $pwauth_email_domain;
 
                // Lookup information about user
                $username = strtolower( $user->getName() );
                $account = posix_getpwnam( $username );
                $gecos = split( ',', $account['gecos'] );
 
                // Set users real name
                $user->setRealName( $gecos[0] );
 
                // Set email if domain is configured
                if (!empty( $pwauth_email_domain ) )  {
                        // Set the email address
                        $user->setEmail( $username.'@'.$pwauth_email_domain );
 
                        // We set the email address, therefore it is valid
                        $user->confirmEmail();
                }
 
                // For security, scramble the password to ensure the user can
                // only login using system password. 
                // This set the password to a 15 byte random string.
                $pass = '';
                for($i=0; $i<15;++$i) $pass .= chr(mt_rand(0,255));
                $user->setPassword($pass);
 
                return true;
        }
 
 
        /**
         * Return true if the wiki should create a new local account automatically
         * when asked to login a user who doesn't exist locally but does in the
         * external auth database.
         *
         * If you don't automatically create accounts, you must still create
         * accounts in some way. It's not possible to authenticate without
         * a local account.
         *
         * This is just a question, and shouldn't perform any actions.
         *
         * @return bool
         * @access public
         */
        function autoCreate() {
                return true;
        }
 
 
        /**
         * Can users change their passwords?
         *
         * @return bool
         */
        function allowPasswordChange() {
                # We can't change users system passwords
                return false;
        }
 
        /**
         * Set the given password in the authentication database.
         * Return true if successful.
         *
         * @param string $password
         * @return bool
         * @access public
         */
        function setPassword( $password ) {
                # We can't change users system passwords
                return false;
        }
 
        /**
         * Update user information in the external authentication database.
         * Return true if successful.
         *
         * @param User $user
         * @return bool
         * @access public
         */
        function updateExternalDB( $user ) {
                # We can't change users details
                return false;
        }
 
        /**
         * Check to see if external accounts can be created.
         * Return true if external accounts can be created.
         * @return bool
         * @access public
         */
        function canCreateAccounts() {
                # We can't create accounts
                return false;
        }
 
        /**
         * Add a user to the external authentication database.
         * Return true if successful.
         *
         * @param User $user
         * @param string $password
         * @return bool
         * @access public
         */
        function addUser( $user, $password ) {
                # We can't create accounts
                return false;
        }
 
 
        /**
         * Return true to prevent logins that don't authenticate here from being
         * checked against the local database's password fields.
         *
         * This is just a question, and shouldn't perform any actions.
         *
         * @return bool
         * @access public
         */
        function strict() {
                # Only allow authentication from system database
                return true;
        }
 
        /**
         * When creating a user account, optionally fill in preferences and such.
         * For instance, you might pull the email address or real name from the
         * external user database.
         *
         * The User object is passed by reference so it can be modified; don't
         * forget the & on your function declaration.
         *
         * @param User $user
         * @access public
         */
        function initUser(&$user) {
                # We do everything in updateUser
        }
 
}
 
 
 
/**
 * Some extension information init
 */
$wgExtensionCredits['other'][] = array(
   'name' => 'PWAuthPlugin',
   'version' => '1.0',
   'author' => 'Nicholas Humfrey',
   'description' => 'Automagic login with system accounts, using pwauth',
   'url' => 'http://www.mediawiki.org/wiki/Extension:PwAuthPlugin'
);
 
 
 
?>

[edit] ToDo

  • Move configuration variables from Plug-in source to LocalSettings.php (best practice?) could pass via new() ?
Personal tools