Table of Contents

PunBB or FluxBB Authentication backend

This backend provides authentication against a PunBB 1.2.x forum installed on the same server. It provides Single-Sign-On for (SSO) the forum and the wiki by reusing PunBB's cookies.

Requirements

Configuration

The backend reuses your PunBB configuration. You just need to enable it and set is the PUN_ROOT define pointing to the installation dir of your PunBB forum. Just add it to your conf/local.protected.php:

local.protected.php
<?php
  $conf['useacl']  =1;
  $conf['authtype']='punbb';
  define('PUN_ROOT','/path/to/punbb/');

This path must be an absolute path, like /var/www/free.fr/2/8/mysite/punbb/ for example and must end with a slash /.

To have your admin users recognized you need to set your superuser option to the name of the PunBB administrator group. How this group is named, varies with the used language of your forum. In a English setup it is usually @Administrators, while French users might need to use @Administrateurs.

Source and Installation with PunBB 1.2.x or FluxBB 1.2.x

Up to DokuWiki 2008-05-05 this backend was included in the DokuWiki install. Newer versions no longer come with this backend.

To install the backend, create a inc/auth/punbb.class.php file and copy and paste the following code:

punbb.class.php
<?php
/**
 * PunBB auth backend
 *
 * Uses external Trust mechanism to check against PunBB's
 * user cookie. PunBB's PUN_ROOT must be defined correctly.
 *
 * @author    Andreas Gohr <andi@splitbrain.org>
 */
 
if(!defined('PUN_ROOT')) define('PUN_ROOT', DOKU_INC.'../forum/');
if(get_magic_quotes_gpc()){
  nice_die('Sorry the punbb auth backend requires the PHP option
  <a href="http://www.php.net/manual/en/ref.info.php#ini.magic-quotes-gpc">magic_quotes_gpc</a>
  to be disabled for proper operation. Either setup your PHP install accordingly or
  choose a different auth backend.');
}
 
require_once PUN_ROOT.'include/common.php';
require_once DOKU_INC.'inc/auth/mysql.class.php';
 
#dbg($GLOBALS);
#dbg($pun_user);

class auth_punbb extends auth_mysql {
 
  /**
   * Constructor.
   *
   * Sets additional capabilities and config strings
   */
  function auth_punbb(){
    global $conf;
    $this->cando['external'] = true;
    $this->cando['logoff']   = true;
 
    // make sure we use a crypt understood by punbb
    if(function_exists('sha1')){
      $conf['passcrypt'] = 'sha1';
    }else{
      $conf['passcrypt'] = 'md5';
    }
 
    // get global vars from PunBB config
    global $db_host;
    global $db_name;
    global $db_username;
    global $db_password;
    global $db_prefix;
 
    // now set up the mysql config strings
    $conf['auth']['mysql']['server']   = $db_host;
    $conf['auth']['mysql']['user']     = $db_username;
    $conf['auth']['mysql']['password'] = $db_password;
    $conf['auth']['mysql']['database'] = $db_name;
 
    $conf['auth']['mysql']['checkPass']   = "SELECT u.password AS pass
                                               FROM ${db_prefix}users AS u, ${db_prefix}groups AS g
                                              WHERE u.group_id = g.g_id
                                                AND u.username = '%{user}'
                                                AND g.g_title   != 'Guest'";
    $conf['auth']['mysql']['getUserInfo'] = "SELECT password AS pass, realname AS name, email AS mail,
                                                    id, g_title as `group`
                                               FROM ${db_prefix}users AS u, ${db_prefix}groups AS g
                                              WHERE u.group_id = g.g_id
                                                AND u.username = '%{user}'";
    $conf['auth']['mysql']['getGroups']   = "SELECT g.g_title as `group`
                                               FROM ${db_prefix}users AS u, ${db_prefix}groups AS g
                                              WHERE u.group_id = g.g_id
                                                AND u.username = '%{user}'";
    $conf['auth']['mysql']['getUsers']    = "SELECT DISTINCT u.username AS user
                                               FROM ${db_prefix}users AS u, ${db_prefix}groups AS g
                                              WHERE u.group_id = g.g_id";
    $conf['auth']['mysql']['FilterLogin'] = "u.username LIKE '%{user}'";
    $conf['auth']['mysql']['FilterName']  = "u.realname LIKE '%{name}'";
    $conf['auth']['mysql']['FilterEmail'] = "u.email    LIKE '%{email}'";
    $conf['auth']['mysql']['FilterGroup'] = "g.g_title    LIKE '%{group}'";
    $conf['auth']['mysql']['SortOrder']   = "ORDER BY u.username";
    $conf['auth']['mysql']['addUser']     = "INSERT INTO ${db_prefix}users
                                                    (username, password, email, realname)
                                             VALUES ('%{user}', '%{pass}', '%{email}', '%{name}')";
    $conf['auth']['mysql']['addGroup']    = "INSERT INTO ${db_prefix}groups (g_title) VALUES ('%{group}')";
    $conf['auth']['mysql']['addUserGroup']= "UPDATE ${db_prefix}users
                                                SET group_id=%{gid}
                                              WHERE id='%{uid}'";
    $conf['auth']['mysql']['delGroup']    = "DELETE FROM ${db_prefix}groups WHERE g_id='%{gid}'";
    $conf['auth']['mysql']['getUserID']   = "SELECT id FROM ${db_prefix}users WHERE username='%{user}'";
    $conf['auth']['mysql']['updateUser']  = "UPDATE ${db_prefix}users SET";
    $conf['auth']['mysql']['UpdateLogin'] = "username='%{user}'";
    $conf['auth']['mysql']['UpdatePass']  = "password='%{pass}'";
    $conf['auth']['mysql']['UpdateEmail'] = "email='%{email}'";
    $conf['auth']['mysql']['UpdateName']  = "realname='%{name}'";
    $conf['auth']['mysql']['UpdateTarget']= "WHERE id=%{uid}";
    $conf['auth']['mysql']['delUserGroup']= "UPDATE ${db_prefix}users SET g_id=4 WHERE id=%{uid}";
    $conf['auth']['mysql']['getGroupID']  = "SELECT g_id AS id FROM ${db_prefix}groups WHERE g_title='%{group}'";
 
    $conf['auth']['mysql']['TablesToLock']= array("${db_prefix}users", "${db_prefix}users AS u",
                                                  "${db_prefix}groups", "${db_prefix}groups AS g");
 
    $conf['auth']['mysql']['debug'] = 1;
    // call mysql constructor
    $this->auth_mysql();
  }
 
  /**
   * Just checks against the $pun_user variable
   */
  function trustExternal($user,$pass,$sticky=false){
    global $USERINFO;
    global $conf;
    global $lang;
    global $pun_user;
    global $pun_config;
    $sticky ? $sticky = true : $sticky = false; //sanity check
 
    // someone used the login form
    if(!empty($user)){
      if($this->checkPass($user,$pass)){
        $expire = ($sticky) ? time() + 31536000 : 0;
        $uinfo  = $this->getUserData($user);
        pun_setcookie($uinfo['id'], auth_cryptPassword($pass), $expire);
        $pun_user = array();
        $pun_user['password'] = auth_cryptPassword($pass);
        $pun_user['username'] = $user;
        $pun_user['realname'] = $uinfo['name'];
        $pun_user['email']    = $uinfo['mail'];
        $pun_user['g_title']  = $uinfo['group'];
      }else{
        //invalid credentials - log off
        msg($lang['badlogin'],-1);
        auth_logoff();
        return false;
      }
    }
 
    if(isset($pun_user) && !$pun_user['is_guest']){
      // okay we're logged in - set the globals
      $USERINFO['pass'] = $pun_user['password'];
      $USERINFO['name'] = $pun_user['realname'];
      $USERINFO['mail'] = $pun_user['email'];
      $USERINFO['grps'] = array($pun_user['g_title']);
 
      $_SERVER['REMOTE_USER'] = $pun_user['username'];
      $_SESSION[DOKU_COOKIE]['auth']['user'] = $pun_user['username'];
      $_SESSION[DOKU_COOKIE]['auth']['info'] = $USERINFO;
      return true;
    }
 
    // to be sure
    auth_logoff();
    return false;
  }
 
  /**
   * remove punbb cookie on logout
   */
  function logOff(){
    global $pun_user;
    $pun_user = array();
    $pun_user['is_guest'] = 1;
    pun_setcookie(1, random_pass(8), time() + 31536000);
  }
}
//Setup VIM: ex: et ts=2 enc=utf-8 :

Source and Installation - punbb 1.3.x

Up to DokuWiki 2008-05-05 this backend was included in the DokuWiki install. Newer versions no longer come with this backend.

To install the backend, create a inc/auth/punbb.class.php file and copy and paste the following code:

punbb.class.php
<?php
/**
 * PunBB 1.3.x auth backend
 *
 * Uses external Trust mechanism to check against PunBB's
 * user cookie. PunBB's FORUM_ROOT must be defined correctly.
 *
 * @author    Andreas Gohr <andi@splitbrain.org>
 */
 
// needed if you use URL rewrite in you Wiki and Punbb
// i.e.: example.com/wiki/article  and  example.com/punbb/topic/1515/subject/
define('FORUM_IGNORE_REQUEST_URI', 1);
 
// do not confirm the action in punbb, usefull for ajax in dokuwiki
define('FORUM_SKIP_CSRF_CONFIRM', 1);
 
if(!defined('FORUM_ROOT')) define('FORUM_ROOT', DOKU_INC.'../forum/');
if(get_magic_quotes_gpc()){
  nice_die('Sorry the punbb auth backend requires the PHP option
  <a href="http://www.php.net/manual/en/ref.info.php#ini.magic-quotes-gpc">magic_quotes_gpc</a>
  to be disabled for proper operation. Either setup your PHP install accordingly or
  choose a different auth backend.');
}
 
require_once FORUM_ROOT.'include/common.php';
require_once DOKU_INC.'inc/auth/mysql.class.php';
 
#dbg($GLOBALS);
#dbg($forum_user);

class auth_punbb extends auth_mysql {
 
  /**
   * Constructor.
   *
   * Sets additional capabilities and config strings
   */
  function auth_punbb(){
    global $conf;
    $this->cando['external'] = true;
    $this->cando['logoff']   = true;
 
    // make sure we use a crypt understood by punbb
    if(function_exists('sha1')){
      $conf['passcrypt'] = 'sha1';
    }else{
      $conf['passcrypt'] = 'md5';
    }
 
    // get global vars from PunBB config
    global $db_host;
    global $db_name;
    global $db_username;
    global $db_password;
    global $db_prefix;
 
    // now set up the mysql config strings
    $conf['auth']['mysql']['server']   = $db_host;
    $conf['auth']['mysql']['user']     = $db_username;
    $conf['auth']['mysql']['password'] = $db_password;
    $conf['auth']['mysql']['database'] = $db_name;
 
    $conf['auth']['mysql']['checkPass']   = "SELECT u.password AS pass
                                               FROM ${db_prefix}users AS u, ${db_prefix}groups AS g
                                              WHERE u.group_id = g.g_id
                                                AND u.username = '%{user}'
                                                AND g.g_title   != 'Guest'";
    $conf['auth']['mysql']['getUserInfo'] = "SELECT password AS pass, realname AS name, email AS mail,
                                                    id, g_title as `group`
                                               FROM ${db_prefix}users AS u, ${db_prefix}groups AS g
                                              WHERE u.group_id = g.g_id
                                                AND u.username = '%{user}'";
    $conf['auth']['mysql']['getGroups']   = "SELECT g.g_title as `group`
                                               FROM ${db_prefix}users AS u, ${db_prefix}groups AS g
                                              WHERE u.group_id = g.g_id
                                                AND u.username = '%{user}'";
    $conf['auth']['mysql']['getUsers']    = "SELECT DISTINCT u.username AS user
                                               FROM ${db_prefix}users AS u, ${db_prefix}groups AS g
                                              WHERE u.group_id = g.g_id";
    $conf['auth']['mysql']['FilterLogin'] = "u.username LIKE '%{user}'";
    $conf['auth']['mysql']['FilterName']  = "u.realname LIKE '%{name}'";
    $conf['auth']['mysql']['FilterEmail'] = "u.email    LIKE '%{email}'";
    $conf['auth']['mysql']['FilterGroup'] = "g.g_title    LIKE '%{group}'";
    $conf['auth']['mysql']['SortOrder']   = "ORDER BY u.username";
    $conf['auth']['mysql']['addUser']     = "INSERT INTO ${db_prefix}users
                                                    (username, password, email, realname)
                                             VALUES ('%{user}', '%{pass}', '%{email}', '%{name}')";
    $conf['auth']['mysql']['addGroup']    = "INSERT INTO ${db_prefix}groups (g_title) VALUES ('%{group}')";
    $conf['auth']['mysql']['addUserGroup']= "UPDATE ${db_prefix}users
                                                SET group_id=%{gid}
                                              WHERE id='%{uid}'";
    $conf['auth']['mysql']['delGroup']    = "DELETE FROM ${db_prefix}groups WHERE g_id='%{gid}'";
    $conf['auth']['mysql']['getUserID']   = "SELECT id FROM ${db_prefix}users WHERE username='%{user}'";
    $conf['auth']['mysql']['updateUser']  = "UPDATE ${db_prefix}users SET";
    $conf['auth']['mysql']['UpdateLogin'] = "username='%{user}'";
    $conf['auth']['mysql']['UpdatePass']  = "password='%{pass}'";
    $conf['auth']['mysql']['UpdateEmail'] = "email='%{email}'";
    $conf['auth']['mysql']['UpdateName']  = "realname='%{name}'";
    $conf['auth']['mysql']['UpdateTarget']= "WHERE id=%{uid}";
    $conf['auth']['mysql']['delUserGroup']= "UPDATE ${db_prefix}users SET g_id=4 WHERE id=%{uid}";
    $conf['auth']['mysql']['getGroupID']  = "SELECT g_id AS id FROM ${db_prefix}groups WHERE g_title='%{group}'";
 
    $conf['auth']['mysql']['TablesToLock']= array("${db_prefix}users", "${db_prefix}users AS u",
                                                  "${db_prefix}groups", "${db_prefix}groups AS g");
 
    $conf['auth']['mysql']['debug'] = 1;
    // call mysql constructor
    $this->auth_mysql();
  }
 
  /**
   * Just checks against the $forum_user variable
   */
  function trustExternal($user,$pass,$sticky=false){
    global $USERINFO;
    global $conf;
    global $lang;
    global $forum_user;
    global $pun_config;
    $sticky ? $sticky = true : $sticky = false; //sanity check
 
    // someone used the login form
    if(!empty($user)){
      if($this->checkPass($user,$pass)){
        $expire = ($sticky) ? time() + 31536000 : 0;
        $uinfo  = $this->getUserData($user);
        forum_setcookie($uinfo['id'], auth_cryptPassword($pass), $expire);
        $forum_user = array();
        $forum_user['password'] = auth_cryptPassword($pass);
        $forum_user['username'] = $user;
        $forum_user['realname'] = $uinfo['name'];
        $forum_user['email']    = $uinfo['mail'];
        $forum_user['g_title']  = $uinfo['group'];
      }else{
        //invalid credentials - log off
        msg($lang['badlogin'],-1);
        auth_logoff();
        return false;
      }
    }
 
    if(isset($forum_user) && !$forum_user['is_guest']){
      // okay we're logged in - set the globals
      $USERINFO['pass'] = $pun_user['password'];
      $USERINFO['name'] = utf8_encode($forum_user['realname']);
      $USERINFO['mail'] = $forum_user['email'];
      $USERINFO['grps'] = array($forum_user['g_title']);
 
      $_SERVER['REMOTE_USER'] = utf8_encode($forum_user['username']);
      $_SESSION[DOKU_COOKIE]['auth']['user'] = utf8_encode($forum_user['username']);
      $_SESSION[DOKU_COOKIE]['auth']['info'] = $USERINFO;
      return true;
    }
 
    // to be sure
    auth_logoff();
    return false;
  }
 
  /**
   * remove punbb cookie on logout
   */
  function logOff(){
    global $forum_user;
    $forum_user = array();
    $forum_user['is_guest'] = 1;
    forum_setcookie(1, random_key(8), time() + 31536000);
  }
}
//Setup VIM: ex: et ts=2 enc=utf-8 :

Source and Installation - FluxBB 1.4

Same instructions as with FluxBB 1.2.x, but there are some functions in the file inc/utf8.php already defined by FluxBB 1.4 (version 1.4.2), these are:

Error message:

**Fatal error: Cannot redeclare utf8_strlen() (previously declared in ......./inc/utf8.php:132) in ......./include/utf8/mbstring/core.php  on line 28**

So we need to edit inc/utf8.php in order to only let DokuWiki define these functions if we're not using FluxBB, by adding an check around these function:

if(!defined('PUN_ROOT')) { ... }

Example: utf8_strlen

replace:

function utf8_strlen($string){
  return strlen(utf8_decode($string));
}

with:

if(!defined('PUN_ROOT')){
	function utf8_strlen($string){
	  return strlen(utf8_decode($string));
	}
}

You'll have to apply these modifications 10 times in inc/utf8.php . olivier id2ndr

dokuwiki 2010-11-07 "Anteater"

With these version a small modification should be done to avoid the error bellow :

Fatal error: Call to a member function query() on a non-object in /var/www/forum/include/functions.php on line 185

PunBB CSRF & Ajax problem

If you want to make ajax-quicksearch work, You should define the constant FORUM_SKIP_CSRF_CONFIRM before including any PunBB code so, the code above should be like below :

define("FORUM_SKIP_CSRF_CONFIRM", 1); 
include PUN_ROOT.'include/common.php';

Dokuwiki 2013-05-10 "Weatherwax"

FIXME CREATE authplugin for in the repository.

Discussion

DokuWiki uses UTF-8 and PunBB ISO8859-1, so this is just a character encoding problem. In order to get the right usernames, open /dokuwiki/inc/auth/punbb.class.php, find (l136 on v. 2007-06-26b) :

    if(isset($pun_user) && !$pun_user['is_guest']){
      // okay we're logged in - set the globals
      $USERINFO['pass'] = $pun_user['password'];
      $USERINFO['name'] = $pun_user['realname'];
      $USERINFO['mail'] = $pun_user['email'];
      $USERINFO['grps'] = array($pun_user['g_title']);
 
      $_SERVER['REMOTE_USER'] = $pun_user['username'];
      $_SESSION[DOKU_COOKIE]['auth']['user'] = $pun_user['username'];
      $_SESSION[DOKU_COOKIE]['auth']['info'] = $USERINFO;
      return true;
    }

And replace by :

    if(isset($pun_user) && !$pun_user['is_guest']){
      // okay we're logged in - set the globals
      $USERINFO['pass'] = $pun_user['password'];
      $USERINFO['name'] = utf8_encode($pun_user['realname']);
      $USERINFO['mail'] = $pun_user['email'];
      $USERINFO['grps'] = array($pun_user['g_title']);
 
      $_SERVER['REMOTE_USER'] = utf8_encode($pun_user['username']);
      $_SESSION[DOKU_COOKIE]['auth']['user'] = utf8_encode($pun_user['username']);
      $_SESSION[DOKU_COOKIE]['auth']['info'] = $USERINFO;
      return true;
    }

Maximilien Thiel 2007-11-13 - 11:00 UTC +01:00

1)
Either disable in your php.ini or use php_value magic_quotes_gpc off in .htaccess