Radius is a authentication and accounting protocol for large departments, somehow similar to ldap. If your department uses RADIUS to manage accounts, you can reuse that accounts for your dokuwiki.
# pear install pecl/radius
Save this under …/dokuwiki/inc/auth/radius.class.php:
<?php /** * RADIUS authentication backend * * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) * @author Sebastian Menge <bastl@users.sf.net> */ define('DOKU_AUTH', dirname(__FILE__)); require_once(DOKU_AUTH.'/basic.class.php'); // FIXME: better way to do this? must we support windows? //load radius extension if required if(!extension_loaded('radius')) { if (preg_match('/windows/i', getenv('OS'))) { dl('php_radius.dll'); } else { dl('radius.so'); } } class auth_radius extends auth_basic { /** * handle to the radius server */ var $radius = null; /** * radius config */ var $cnf = null; /** * Constructor * * Carry out sanity checks to ensure the object is * able to operate. Sets no capabilities because we only auhtenticate via radius * * @author Sebastian Menge <bastl@users.sf.net> */ function auth_radius() { global $conf; $this->cnf = $conf['auth']['radius']; // radius extension is needed if(!function_exists('radius_add_server')) { if ($this->cnf['debug']) msg("Radius err: PHP radius extension not found.",-1,__LINE__,__FILE__); $this->success = false; return; } // FIXME: defaults like this: (e.g. localhost:1812) // if(empty($this->cnf['groupkey'])) $this->cnf['groupkey'] = 'cn'; // get parameters from config $host = $this->cnf['host']; $port = $this->cnf['port']; $secret = $this->cnf['secret']; $timeout = $this->cnf['timeout']; $tries = $this->cnf['tries']; //create handle and add server $this->radius = radius_auth_open(); //try to connect if (!radius_add_server($this->radius,$host,$port,$secret,$timeout,$tries)){ msg("Radius err: ". radius_strerror($this->radius),-1,__LINE__,__FILE__); $this->success = false; return; } // auth_radius currently just handles authentication, so no // capabilities are set } /** * Check user+password [required auth function] * * Checks if the given user exists and the given * plaintext password is correct * * @author Sebastian Menge <bastl@users.sf.net> * @return bool */ function checkPass($user,$pass){ if (! radius_create_request($this->radius,RADIUS_ACCESS_REQUEST)) { msg("Radius err: ". radius_strerror($this->radius),-1,__LINE__,__FILE__); } radius_put_attr($this->radius,RADIUS_USER_NAME,$user); radius_put_attr($this->radius,RADIUS_USER_PASSWORD,$pass); //send the actual request and return result switch (radius_send_request($this->radius)) { case RADIUS_ACCESS_ACCEPT: $data = $this->getUserData($user); msg("Logged in via Radius. Your groups are: ".implode(",",$data['grps']),0); return true; break; case RADIUS_ACCESS_REJECT: return false; break; case RADIUS_ACCESS_CHALLENGE: msg("Radius: CHAP not supported by auth_radius."); return false; break; default: msg('Radius Error: ' . radius_strerror($this->radius),-1,__LINE__,__FILE__); } return false; } /** * Return user info * * Returns info about the given user needs to contain * at least these fields: * * name string full name of the user, for now just $user * mail string email address of the user, for now $user@$mailhost. * $mailhost is set in the config * grps array list of groups the user is in, for now empty. * Could be calculated from the username regexes in the config. * * @author Sebastian Menge <bastl@users.sf.net> */ function getUserData($user){ //mail is user@mailhost $data['mail'] = $user.'@'.$this->cnf['mailhost']; //get groups from config $data['grps'] = array(); global $conf; if (count($conf['auth']['groups']) > 0) { foreach( $conf['auth']['groups'] as $g_name => $g_array) { foreach( $g_array as $g_member ) { if (strcasecmp($user,$g_member) == 0 ) { $data['grps'][] = $g_name; } } } } //if no groups are found place the user in 'defaultgroup' if (count ($data['grps']) == 0) { $data['grps'][] = $this->cnf['defaultgroup']; } //use login name and groups as "full name" $data['name'] = $user." (".implode(", ",$data['grps']).")"; return $data; } } //Setup VIM: ex: et ts=2 enc=utf-8 :
//enable radius auth $conf['authtype'] = 'radius'; //radius Config $conf['auth']['radius']['host'] = 'radius.mycompany.com'; $conf['auth']['radius']['port'] = '0'; //0 reuses data from /etc/services $conf['auth']['radius']['secret'] = 'radiussecret'; $conf['auth']['radius']['timeout'] = '3'; $conf['auth']['radius']['tries'] = '3'; $conf['auth']['radius']['mailhost'] = 'mail.mycompany.com';
This should go to local.protected.php, because the config plugin trashes the “array()” statements. Dont forget to include it with @include(DOKU_CONF.'local.protected.php');
<?php //groups config $conf['auth']['groups']['admin'] = array('user1'); | $conf['auth']['groups']['crew'] = array('user2','user3);Put the following in …/dokuwiki/lib/plugins/config/settings/config.metadata.php to edit the main settings it via the config plugin.
//radius-settings $meta['auth____radius____host'] = array('string'); $meta['auth____radius____port'] = array('string'); $meta['auth____radius____timeout'] = array('string'); $meta['auth____radius____tries'] = array('string'); $meta['auth____radius____secret'] = array('password'); $meta['auth____radius____mailhost'] = array('string'); $meta['auth____radius____defaultgroup'] = array('string');
Please leave your comments here.
Hi, you asked on IRC how to hook into DokuWikis message system. The function you`re looking for is msg(), you`ll find it in inc/infoutils.php. Regards — Michael Klier 2007-09-30 22:17
Thanks, it seems to be a redirection problem that occurs at login. The msgs are not displayed.
The groups handling could be useful for ldap too …
I'm looking for a good workaround for the arrays of users in local.protected.php. Please help.
Added an if statement to 'getUserData' to place the user in 'defaultgroup' if no other groups are found for the user. - jpbarto of freeshell dot org
Small changes 2007-12-14 : User in groups are now case insensitive, correct the message to print all group when a user login (and not Array()…). - marc of practeo dot ch