Here’s a quick recipe for getting a server up with MediaWiki running and having Active Directory Logins working with it… I’ll warn you, there are other ways of doing this. I find this to satisfy my needs, but if you manage to cause the world to implode, I won’t be held responsible.
Step 1: Set up your server
I created an Ubuntu 10.10 server VM for this, use whatever if you have some sort of issue against doing the same as me.
Step 2: Get Centrify Going
My friend told me about “Centrify” the other day. It’s a package you can install to help make Active Directory Logins simple. To install it, you have to first uncomment the partner repos in /etc/apt/sources.list – then install it via “apt-get install centrifydc“.
To activate Centrify, run “adjoin -w AD-NAME“, if you need more options, use “adjoin –help” to learn more.
Reboot your machine and confirm you can login with your credentials in Active Directory.
Step 3: Install & Configure MediaWiki
Go through the regular fun of setting up MediaWiki.. So install Apache2, php5 and whatever database you like.
Once you’ve got the base install of MediaWiki going, add the following lines to your LocalSettings.php
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
Then, dump the following file to ./extentions/PwAuthPlugin.php
<?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); //Removed by James for those using Centrify, will cause ugliness 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' ); ?>
Basically all of that plugin is from here. But I found I had to disable saving of passwords in the function “updateUser()” in order for this to work with Centrify in my environment.
Step 4: Send me Beer
Now that you’re happily up and running with AD auths in MediaWiki send me a beer via Paypal: