[ABD] Apache/Kerberos single sign-on with LDAP/AD connection

Any abandoned MODs will be moved to this forum.

WARNING: MODs in this forum are not currently being supported or maintained by the original MOD author. Proceed at your own risk.
Forum rules
IMPORTANT: MOD Development Forum rules

WARNING: MODs in this forum are not currently being supported nor updated by the original MOD author. Proceed at your own risk.
Locked
barenaked_dali
Registered User
Posts: 3
Joined: Thu May 28, 2009 11:46 am

[ABD] Apache/Kerberos single sign-on with LDAP/AD connection

Post by barenaked_dali » Thu May 28, 2009 12:02 pm

Hi, not sure if this is the right place for this, but I've put together a new auth module that enables single sign-on via Apache/Kerberos in phpBB3 3.0.4. Tried to figure out how to submit it, but the rules indicate that community members are not allowed to submit new modules.

It's basically a combination of auth_apache and auth_ldap with Apache using mod_auth_kerb for authentication. When a (corporate intranet) user surfs to the forum, he/she is authenticated by Apache and automatically registered (if not already a member).

Since I can't attach files, here's the code for auth_kerbsso.php:

Code: Select all

<?php
/**
*
* Apache Kerberos SSO with LDAP connection.
* Basically Apache's mod_auth_kerb with a combination of phpBB3's auth_apache and auth_ldap.
* Reference info: http://wiki.phpbb.com/Authentication_plugins
*
* Authentication plug-ins is largely down to Sergey Kanareykin, our thanks to him.
*
* @package login
* @version $Id: auth_kerbsso.php 2009-05-27 00:00:00Z barenaked_dali $
* @copyright (c) 2005 phpBB Group
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
*
*/
 
/**
* @ignore
*/
if (!defined('IN_PHPBB'))
{
	exit;
}
 
/**
* retrieve user information from ldap
*/
 
function kerbsso_get_ldap_info($username)
{
       global $config, $user;
 
        if (!@extension_loaded('ldap'))
        {
                return $user->lang['LDAP_NO_LDAP_EXTENSION'];
        }
 
        $config['ldap_port'] = (int) $config['ldap_port'];
        if ($config['ldap_port'])
        {
                $ldap = @ldap_connect($config['ldap_server'], $config['ldap_port']);
        }
        else
        {
                $ldap = @ldap_connect($config['ldap_server']);
        }
 
        if (!$ldap)
        {
                return $user->lang['LDAP_NO_SERVER_CONNECTION'];
        }
 
        @ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
        @ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
 
        if ($config['ldap_user'] || $config['ldap_password'])
        {
                if (!@ldap_bind($ldap, htmlspecialchars_decode($config['ldap_user']), htmlspecialchars_decode($config['ldap_password'])))
                {
                        return $user->lang['LDAP_INCORRECT_USER_PASSWORD'];
                }
        }
 
        // ldap_connect only checks whether the specified server is valid, so the connection might still fail
        $search = @ldap_search(
                $ldap,
                $config['ldap_base_dn'],
                kerbsso_ldap_user_filter($username),
                (empty($config['ldap_email'])) ? array($config['ldap_uid']) : array($config['ldap_uid'], $config['ldap_email']),
                0,
                1
        );
 
        if ($search === false)
        {
                return $user->lang['LDAP_NO_SERVER_CONNECTION'];
        }
 
        $result = @ldap_get_entries($ldap, $search);
 
        @ldap_close($ldap);
 
        return $result;
}
 
 
/**
* 1: Verify that Apache is authenticating (returning REMOTE_USER).
* 2: Connect to ldap server and check if kerberos supplied username exists in directory.
* Only allow changing authentication to kerbsso if:
* - apache is authenticating
* - we can connect to the ldap server
* - the current user exists in the directory (and has an e-mail address).
* Called in acp_board while setting authentication plugins
*/
function init_kerbsso()
{
        global $config, $user;
 
        // apache authentication check
        if (isset($_SERVER['REMOTE_USER']))
        {
                // get kerberos user from apache, username@REALM, strip @REALM.
                list($kerbuser,$realm) = split("@", strtolower($_SERVER['REMOTE_USER']), 2);
                if ($user->data['username'] !== $kerbuser)
                {
                         return $user->lang['APACHE_SETUP_BEFORE_USE'];
                }
        }
        else
        {
                // apache is not (correctly) configured
                return $user->lang['APACHE_SETUP_BEFORE_USE'];
        }
 
        // get info about current user from ldap.
        $result = @kerbsso_get_ldap_info($kerbuser);
 
        if (!is_array($result) || sizeof($result) < 2)
        {
                unset($result);
                return sprintf($user->lang['LDAP_NO_IDENTITY'], $user->data['username']);
        }
 
        if (!empty($config['ldap_email']) && !isset($result[0][$config['ldap_email']]))
        {
                unset($result);
                return $user->lang['LDAP_NO_EMAIL'];
        }
 
        unset($result); 
        return false;
}
 
 
/**
* Login function
*/
function login_kerbsso(&$username, &$password)
{
	global $db, $config, $user;
 
        // get kerberos user from apache, username@REALM, strip @REALM.
        list($kerbuser,$realm) = split("@", strtolower($_SERVER['REMOTE_USER']), 2);
 
        // set dummy password. apache has authenticated the user.
        $password = "ApacheSSO";
 
	if (!$username || $kerbuser !== $username)
	{
		return array(
			'status'	=> LOGIN_ERROR_USERNAME,
			'error_msg'	=> 'LOGIN_ERROR_USERNAME',
			'user_row'	=> array('user_id' => ANONYMOUS),
		);
	}
 
	if (!@extension_loaded('ldap'))
	{
		return array(
			'status'	=> LOGIN_ERROR_EXTERNAL_AUTH,
			'error_msg'	=> 'LDAP_NO_LDAP_EXTENSION',
			'user_row'	=> array('user_id' => ANONYMOUS),
		);
	}
 
	$ldap_result = @kerbsso_get_ldap_info($kerbuser);
 
	if (is_array($ldap_result) && sizeof($ldap_result) > 1)
	{
 
		$sql ='SELECT user_id, username, user_password, user_passchg, user_email, user_type
			FROM ' . USERS_TABLE . "
			WHERE username_clean = '" . $db->sql_escape(utf8_clean_string($username)) . "'";
		$result = $db->sql_query($sql);
		$row = $db->sql_fetchrow($result);
		$db->sql_freeresult($result);
 
		if ($row) // Existing user
		{
			unset($ldap_result);
 
			// User inactive...
			if ($row['user_type'] == USER_INACTIVE || $row['user_type'] == USER_IGNORE)
			{
				return array(
					'status'	=> LOGIN_ERROR_ACTIVE,
					'error_msg'	=> 'ACTIVE_ERROR',
					'user_row'	=> $row,
				);
			}
 
			// Successful login... set user_login_attempts to zero...
			return array(
				'status'	=> LOGIN_SUCCESS,
				'error_msg'	=> false,
				'user_row'	=> $row,
			);
		}
		else // New user
		{
			// retrieve default group id
			$sql = 'SELECT group_id
				FROM ' . GROUPS_TABLE . "
				WHERE group_name = '" . $db->sql_escape('REGISTERED') . "'
					AND group_type = " . GROUP_SPECIAL;
			$result = $db->sql_query($sql);
			$row = $db->sql_fetchrow($result);
			$db->sql_freeresult($result);
 
			if (!$row)
			{
				trigger_error('NO_GROUP');
			}
 
			// generate user account data
			$ldap_user_row = array(
				'username'	=> $username,
				'user_password'	=> phpbb_hash($password),
				'user_email'	=> (!empty($config['ldap_email'])) ? $ldap_result[0][$config['ldap_email']][0] : '',
				'group_id'	=> (int) $row['group_id'],
				'user_type'	=> USER_NORMAL,
				'user_ip'	=> $user->ip,
			);
 
			unset($ldap_result);
 
			// this is the user's first login so create an empty profile
			return array(
				'status'	=> LOGIN_SUCCESS_CREATE_PROFILE,
				'error_msg'	=> false,
				'user_row'	=> $ldap_user_row,
			);
		}
	}
 
	return array(
		'status'	=> LOGIN_ERROR_USERNAME,
		'error_msg'	=> 'LOGIN_ERROR_USERNAME',
		'user_row'	=> array('user_id' => ANONYMOUS),
	);
}
 
/**
* Autologin function
*
* @return array containing the user row or empty if no auto login should take place
*/
 
function autologin_kerbsso()
{
        global $db;
 
        if (!isset($_SERVER['REMOTE_USER']))
        {
                return array();
        }
 
        // get kerberos user from apache, username@REALM, strip @REALM.
        list($kerbuser,$realm) = split("@", strtolower($_SERVER['REMOTE_USER']), 2);
 
        if (!empty($kerbuser))
        {
                $sql = 'SELECT *
                        FROM ' . USERS_TABLE . "
                        WHERE username = '" . $db->sql_escape($kerbuser) . "'";
                $result = $db->sql_query($sql);
                $row = $db->sql_fetchrow($result);
                $db->sql_freeresult($result);
 
                if ($row)
                {
                        return ($row['user_type'] == USER_INACTIVE || $row['user_type'] == USER_IGNORE) ? array() : $row;
                }
 
                if (!function_exists('user_add'))
                {
                        global $phpbb_root_path, $phpEx;
 
                        include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
                }
 
                // create the user if he does not exist yet.
                user_add(kerbsso_user_row($kerbuser));
 
                $sql = 'SELECT *
                        FROM ' . USERS_TABLE . "
                        WHERE username_clean = '" . $db->sql_escape(utf8_clean_string($kerbuser)) . "'";
                $result = $db->sql_query($sql);
                $row = $db->sql_fetchrow($result);
                $db->sql_freeresult($result);
 
                if ($row)
                {
                        return $row;
                }
        }
 
        return array();
}
 
/**
* This function generates an array which can be passed to the user_add function in order to create a user
*/
function kerbsso_user_row($username)
{
        global $db, $config, $user;
 
        // first retrieve default group id
        $sql = 'SELECT group_id
                FROM ' . GROUPS_TABLE . "
                WHERE group_name = '" . $db->sql_escape('REGISTERED') . "'
                        AND group_type = " . GROUP_SPECIAL;
        $result = $db->sql_query($sql);
        $row = $db->sql_fetchrow($result);
        $db->sql_freeresult($result);
 
        if (!$row)
        {
                trigger_error('NO_GROUP');
        }
 
        // get ldap info
        $ldap_userinfo = @kerbsso_get_ldap_info($username);
 
        // generate user account data. dummy password.
        $user_row =  array(
                'username'	=> $username,
                'user_password'	=> phpbb_hash("ApacheSSO"),
                'user_email'	=> (!empty($config['ldap_email'])) ? $ldap_userinfo[0][$config['ldap_email']][0] : '',
                'group_id'	=> (int) $row['group_id'],
                'user_type'	=> USER_NORMAL,
                'user_ip'	=> $user->ip,
        );
        unset($ldap_userinfo);
 
        return $user_row;
}
 
/**
* The session validation function checks whether the user is still logged in
*
* @return boolean true if the given user is authenticated or false if the session should be closed
*/
function validate_session_kerbsso($user)
{
        if (!isset($_SERVER['REMOTE_USER']))
        {
                return false;
        }
 
        // get kerberos user from apache, username@REALM, strip @REALM.
        list($kerbuser,$realm) = split("@", strtolower($_SERVER['REMOTE_USER']), 2);
 
        return ($kerbuser === $user['username']) ? true : false;
}
 
/**
* Generates a filter string for ldap_search to find a user
*
* @param        $username       string  Username identifying the searched user
*
* @return                       string  A filter string for ldap_search
*/
function kerbsso_ldap_user_filter($username)
{
        global $config;
 
        $filter = '(' . $config['ldap_uid'] . '=' . kerbsso_ldap_escape(htmlspecialchars_decode($username)) . ')';
        if ($config['ldap_user_filter'])
        {
                $filter = "(&$filter({$config['ldap_user_filter']}))";
        }
        return $filter;
}
 
/**
* Escapes an LDAP AttributeValue
*/
function kerbsso_ldap_escape($string)
{
        return str_replace(array('*', '\\', '(', ')'), array('\\*', '\\\\', '\\(', '\\)'), $string);
}
 
/**
* Required LDAP fields in the authentication admin panel are created by auth_ldap.php.
*/
 
?>
I know how to get Apache with mod_auth_kerb and phpBB3 with kerbsso running, but I'll wait for approval of the above code before posting it.
Last edited by barenaked_dali on Fri May 29, 2009 6:47 am, edited 3 times in total.

barenaked_dali
Registered User
Posts: 3
Joined: Thu May 28, 2009 11:46 am

Re: [DEV] Apache/Kerberos single sign-on with LDAP/AD connection

Post by barenaked_dali » Fri May 29, 2009 6:42 am

Updated module, uses kerbsso_user_row in login_kerbsso.

Code: Select all

<?php
/**
*
* Apache Kerberos SSO with LDAP connection.
* Basically Apache's mod_auth_kerb with a combination of phpBB3's auth_apache and auth_ldap.
* Reference info: http://wiki.phpbb.com/Authentication_plugins
*
* Authentication plug-ins is largely down to Sergey Kanareykin, our thanks to him.
*
* @package login
* @version $Id: auth_kerbsso.php 2009-05-29 00:00:00Z barenaked_dali $
* @copyright (c) 2005 phpBB Group
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
*
*/
 
/**
* @ignore
*/
if (!defined('IN_PHPBB'))
{
	exit;
}
 
/**
* retrieve user information from ldap
*/
 
function kerbsso_get_ldap_info($username)
{
       global $config, $user;
 
        if (!@extension_loaded('ldap'))
        {
                return $user->lang['LDAP_NO_LDAP_EXTENSION'];
        }
 
        $config['ldap_port'] = (int) $config['ldap_port'];
        if ($config['ldap_port'])
        {
                $ldap = @ldap_connect($config['ldap_server'], $config['ldap_port']);
        }
        else
        {
                $ldap = @ldap_connect($config['ldap_server']);
        }
 
        if (!$ldap)
        {
                return $user->lang['LDAP_NO_SERVER_CONNECTION'];
        }
 
        @ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
        @ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
 
        if ($config['ldap_user'] || $config['ldap_password'])
        {
                if (!@ldap_bind($ldap, htmlspecialchars_decode($config['ldap_user']), htmlspecialchars_decode($config['ldap_password'])))
                {
                        return $user->lang['LDAP_INCORRECT_USER_PASSWORD'];
                }
        }
 
        // ldap_connect only checks whether the specified server is valid, so the connection might still fail
        $search = @ldap_search(
                $ldap,
                $config['ldap_base_dn'],
                kerbsso_ldap_user_filter($username),
                (empty($config['ldap_email'])) ? array($config['ldap_uid']) : array($config['ldap_uid'], $config['ldap_email']),
                0,
                1
        );
 
        if ($search === false)
        {
                return $user->lang['LDAP_NO_SERVER_CONNECTION'];
        }
 
        $result = @ldap_get_entries($ldap, $search);
 
        @ldap_close($ldap);
 
        return $result;
}
 
 
/**
* 1: Verify that Apache is authenticating (returning REMOTE_USER).
* 2: Connect to ldap server and check if kerberos supplied username exists in directory.
* Only allow changing authentication to kerbsso if:
* - apache is authenticating
* - we can connect to the ldap server
* - the current user exists in the directory (and has an e-mail address).
* Called in acp_board while setting authentication plugins
*/
function init_kerbsso()
{
        global $config, $user;
 
        // apache authentication check
        if (isset($_SERVER['REMOTE_USER']))
        {
                // get kerberos user from apache, username@REALM, strip @REALM.
                list($kerbuser,$realm) = split("@", strtolower($_SERVER['REMOTE_USER']), 2);
                if ($user->data['username'] !== $kerbuser)
                {
                         return $user->lang['APACHE_SETUP_BEFORE_USE'];
                }
        }
        else
        {
                // apache is not (correctly) configured
                return $user->lang['APACHE_SETUP_BEFORE_USE'];
        }
 
        // get info about current user from ldap.
        $result = @kerbsso_get_ldap_info($kerbuser);
 
        if (!is_array($result) || sizeof($result) < 2)
        {
                unset($result);
                return sprintf($user->lang['LDAP_NO_IDENTITY'], $user->data['username']);
        }
 
        if (!empty($config['ldap_email']) && !isset($result[0][$config['ldap_email']]))
        {
                unset($result);
                return $user->lang['LDAP_NO_EMAIL'];
        }
 
        unset($result); 
        return false;
}
 
 
/**
* Login function
*/
function login_kerbsso(&$username, &$password)
{
	global $db, $config, $user;
 
        // get kerberos user from apache, username@REALM, strip @REALM.
        list($kerbuser,$realm) = split("@", strtolower($_SERVER['REMOTE_USER']), 2);
 
        // set dummy password. apache has authenticated the user.
        $password = "ApacheSSO";
 
	if (!$username || $kerbuser !== $username)
	{
		return array(
			'status'	=> LOGIN_ERROR_USERNAME,
			'error_msg'	=> 'LOGIN_ERROR_USERNAME',
			'user_row'	=> array('user_id' => ANONYMOUS),
		);
	}
 
	if (!@extension_loaded('ldap'))
	{
		return array(
			'status'	=> LOGIN_ERROR_EXTERNAL_AUTH,
			'error_msg'	=> 'LDAP_NO_LDAP_EXTENSION',
			'user_row'	=> array('user_id' => ANONYMOUS),
		);
	}
 
	$ldap_result = @kerbsso_get_ldap_info($kerbuser);
 
	if (is_array($ldap_result) && sizeof($ldap_result) > 1)
	{
 
		$sql ='SELECT user_id, username, user_password, user_passchg, user_email, user_type
			FROM ' . USERS_TABLE . "
			WHERE username_clean = '" . $db->sql_escape(utf8_clean_string($username)) . "'";
		$result = $db->sql_query($sql);
		$row = $db->sql_fetchrow($result);
		$db->sql_freeresult($result);
 
		if ($row) // Existing user
		{
			unset($ldap_result);
 
			// User inactive...
			if ($row['user_type'] == USER_INACTIVE || $row['user_type'] == USER_IGNORE)
			{
				return array(
					'status'	=> LOGIN_ERROR_ACTIVE,
					'error_msg'	=> 'ACTIVE_ERROR',
					'user_row'	=> $row,
				);
			}
 
			// Successful login... set user_login_attempts to zero...
			return array(
				'status'	=> LOGIN_SUCCESS,
				'error_msg'	=> false,
				'user_row'	=> $row,
			);
		}
		else // New user
		{
                        $user_row = kerbsso_user_row($username);
			unset($ldap_result);
 
			// this is the user's first login so create an empty profile
			return array(
				'status'	=> LOGIN_SUCCESS_CREATE_PROFILE,
				'error_msg'	=> false,
				'user_row'	=> $user_row,
			);
		}
	}
 
	return array(
		'status'	=> LOGIN_ERROR_USERNAME,
		'error_msg'	=> 'LOGIN_ERROR_USERNAME',
		'user_row'	=> array('user_id' => ANONYMOUS),
	);
}
 
/**
* Autologin function
*
* @return array containing the user row or empty if no auto login should take place
*/
 
function autologin_kerbsso()
{
        global $db;
 
        if (!isset($_SERVER['REMOTE_USER']))
        {
                return array();
        }
 
        // get kerberos user from apache, username@REALM, strip @REALM.
        list($kerbuser,$realm) = split("@", strtolower($_SERVER['REMOTE_USER']), 2);
 
        if (!empty($kerbuser))
        {
                // existing user?
                $sql = 'SELECT *
                        FROM ' . USERS_TABLE . "
                        WHERE username = '" . $db->sql_escape($kerbuser) . "'";
                $result = $db->sql_query($sql);
                $row = $db->sql_fetchrow($result);
                $db->sql_freeresult($result);
 
                if ($row)
                {
                        return ($row['user_type'] == USER_INACTIVE || $row['user_type'] == USER_IGNORE) ? array() : $row;
                }
 
                // new user, automatically create.
                if (!function_exists('user_add'))
                {
                        global $phpbb_root_path, $phpEx;
 
                        include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
                }
 
                user_add(kerbsso_user_row($kerbuser));
 
                $sql = 'SELECT *
                        FROM ' . USERS_TABLE . "
                        WHERE username_clean = '" . $db->sql_escape(utf8_clean_string($kerbuser)) . "'";
                $result = $db->sql_query($sql);
                $row = $db->sql_fetchrow($result);
                $db->sql_freeresult($result);
 
                if ($row)
                {
                        return $row;
                }
        }
 
        return array();
}
 
/**
* This function generates an array which can be passed to the user_add function in order to create a user
*/
function kerbsso_user_row($username)
{
        global $db, $config, $user;
 
        // first retrieve default group id
        $sql = 'SELECT group_id
                FROM ' . GROUPS_TABLE . "
                WHERE group_name = '" . $db->sql_escape('REGISTERED') . "'
                        AND group_type = " . GROUP_SPECIAL;
        $result = $db->sql_query($sql);
        $row = $db->sql_fetchrow($result);
        $db->sql_freeresult($result);
 
        if (!$row)
        {
                trigger_error('NO_GROUP');
        }
 
        // get ldap info
        $ldap_userinfo = @kerbsso_get_ldap_info($username);
 
        // generate user account data. dummy password.
        $user_row = array(
                'username'	=> $username,
                'user_password'	=> phpbb_hash("ApacheSSO"),
                'user_email'	=> (!empty($config['ldap_email'])) ? $ldap_userinfo[0][$config['ldap_email']][0] : '',
                'group_id'	=> (int) $row['group_id'],
                'user_type'	=> USER_NORMAL,
                'user_ip'	=> $user->ip,
        );
        unset($ldap_userinfo);
 
        return $user_row;
}
 
/**
* The session validation function checks whether the user is still logged in
*
* @return boolean true if the given user is authenticated or false if the session should be closed
*/
function validate_session_kerbsso($user)
{
        if (!isset($_SERVER['REMOTE_USER']))
        {
                return false;
        }
 
        // get kerberos user from apache, username@REALM, strip @REALM.
        list($kerbuser,$realm) = split("@", strtolower($_SERVER['REMOTE_USER']), 2);
 
        return ($kerbuser === $user['username']) ? true : false;
}
 
/**
* Generates a filter string for ldap_search to find a user
*
* @param        $username       string  Username identifying the searched user
*
* @return                       string  A filter string for ldap_search
*/
function kerbsso_ldap_user_filter($username)
{
        global $config;
 
        $filter = '(' . $config['ldap_uid'] . '=' . kerbsso_ldap_escape(htmlspecialchars_decode($username)) . ')';
        if ($config['ldap_user_filter'])
        {
                $filter = "(&$filter({$config['ldap_user_filter']}))";
        }
        return $filter;
}
 
/**
* Escapes an LDAP AttributeValue
*/
function kerbsso_ldap_escape($string)
{
        return str_replace(array('*', '\\', '(', ')'), array('\\*', '\\\\', '\\(', '\\)'), $string);
}
 
/**
* Required LDAP fields in the authentication admin panel are created by auth_ldap.php.
*/
 
?>
Here's the instruction on how to use kerbsso with Apache on Linux/Unix (not Apache on Windows, there is no supported mod_auth_kerb).

SSO (Single Sign-On, aka seamless authentication) tested with Windows XP SP3 (member of AD domain), Internet Explorer 6 and 8, Mozilla Firefox 3.

Apache SSO with Kerberos authentication

Reference - http://www.itefix.no/i2/node/11683.

CentOS commands used as examples, adapt to your environment.

This instruction uses servername.yourdomain.com as illustration, replace with your phpBB3 server name and DNS domain/AD realm.

Note: Kerberos is case sensitive, if it is all caps - it should be!

- Install Kerberos client, yum install krb5-workstation
- Install mod_auth_kerb: yum install mod_auth_kerb
- Configure Kerberos if necessary, sample /etc/krb5.conf:

Code: Select all

[logging]
 default = FILE:/var/log/krb5libs.log
 kdc = FILE:/var/log/krb5kdc.log
 admin_server = FILE:/var/log/kadmind.log

[libdefaults]
 default_realm = YOURDOMAIN.COM
 ticket_lifetime = 24h
 forwardable = yes

[realms]
 YOURDOMAIN.COM = {
  kdc = dc1.yourdomain.com
  admin_server = dc1.yourdomain.com
  default_domain = yourdomain.com
 }

[domain_realm]
 dokuwiki.yourdomain.com = YOURDOMAIN.COM
 .yourdomain.com = YOURDOMAIN.COM
 yourdomain.com = YOURDOMAIN.COM

[appdefaults]
 pam = {
  debug = false
   ticket_lifetime = 36000
   renew_lifetime = 36000
   forwardable = true
   krb4_convert = false
 }
- Verify that the time on the Linux server is within 5 minutes of the Active Directory server. Otherwise Kerberos will not authenticate.
- Verify that the Kerberos environment is working by running:

Code: Select all

kinit username@YOURDOMAIN.COM
klist
kdestroy
- Create a keytab file for your phpbb3 server. Make sure you have created a non-admin user in Active Directory with no password expiration. Run this as a Domain Admin on a Windows server with Support Tools installed:

Code: Select all

ktpass -princ HTTP/servername.yourdomain.com@YOURDOMAIN.COM -mapuser name_of_ad_user_you_have_created -crypto DES-CBC-MD5 -ptype KRB5_NT_PRINCIPAL -mapop set +desonly -pass the_ad_users_password -out servername.HTTP.keytab
- If no errors occurred, copy the keytab file to /etc/httpd/conf/.
- Create/update /etc/httpd/conf.d/phpbb3.conf, example with virtual host:

Code: Select all

<VirtualHost *:80>
  ServerName forum.yourdomain.com
  ServerAlias forum
  DocumentRoot /var/www/html/phpBB3
 
  php_value allow_call_time_pass_reference On
 
  <Directory "/var/www/html/phpBB3">
    # Kerberos Auth
    AuthType Kerberos
    KrbAuthRealms YOURDOMAIN.COM
    KrbServiceName HTTP
    Krb5Keytab /etc/httpd/conf/servername.HTTP.keytab
    KrbMethodNegotiate on
    KrbMethodK5Passwd on
    require valid-user
  </Directory>
</VirtualHost>
- Restart apache, service httpd restart

Activate kerbsso in phpBB3

- Make sure that you have php-ldap installed, yum install php-ldap
- Make sure that your phpBB3 admin user has a username that also exists in your LDAP directory (in the base dn configured below). Otherwise phpBB3 won't allow you to activate kerbsso. Password is irrelevant, but the username has to exist.
- Configure your web browser for SPNEGO:
  • - Internet Explorer: add the forum name (virtual host if applicable) to local intranet zone.
    - Mozilla Firefox: add the server name (virtual host if applicable) to network.negotiate-auth.trusted-uris.
- Surf to the forum using the servername that Apache authenticates, in this example http://forum.yourdomain.com (or http://forum). If you get a login prompt, Apache SSO is not working or your web browser is not correctly configured for SPNEGO.
- Log on to phpBB3 using your admin user, with your phpBB3 password.
- Verify that Apache has set REMOTE_USER by going to ACP -> GENERAL tab -> QUICK ACCESS -> PHP Information. If not, you probably used the wrong servername in your browser.
- ACP -> GENERAL tab -> Client Communication -> Authentication. Choose Kerbsso.
- If you get a blank page, verify that auth_kerbsso.php is correct (do a "php -l /var/www/html/phpBB3/includes/auth/auth_kerbsso.php").
- Configure kerbsso (example):
  • - LDAP server name: dc1.yourdomain.com
    - LDAP base dn: ou=your users,dc=yourdomain,dc=com
    - LDAP uid: the attribute that matches your REMOTE_USER username (not including realm), probably sAMAccountName if it's Active Directory.
    - LDAP e-mail attribute: mail if it's Active Directory, all users need to have it
    - LDAP user dn: the user that phpBB3 will use to retrieve info from LDAP, e g cn=phpbbldap,cn=users,dc=yourdomain,dc=com
    - LDAP password: the password for the LDAP user.
- Submit.
- Test your configuration by starting a new browser and connect to your server (using the correct servername for Apache authentication).
- Also test using an LDAP user that doesn't have a phpBB3 user, it should be automatically created in the phpbb3 database.
- If you have problems logging in, edit /var/www/html/phpBB3/cache/data_global.php and set auth_metod to your previous method (probably 'db').
- Some troubleshooting tips:
  • - Did you restart Apache after configuring mod_auth_kerb?
    - Try using the FQDN of your server.
    - Are you using the correct name to connect to the server? It has to be the one the Apache is configured to authenticate for, in this example it's forum.yourdomain.com, not servername.yourdomain.com.
    - If the web browser displays a login window, try logging in with your LDAP username (no domain) and password.
    - Check all kerberos files for case inconsistencies.
    - Review ths instruction from start to finish.

ihayhurst
Registered User
Posts: 1
Joined: Mon Jul 20, 2009 2:48 pm

Re: [DEV] Apache/Kerberos single sign-on with LDAP/AD connection

Post by ihayhurst » Mon Jul 20, 2009 3:03 pm

The Single sign on code for kerberos worked a treat using mod_auth_ntlm_winbind in apache withe the following alterations

all instances of

Code: Select all

list($kerbuser,$realm) = split("@", strtolower($_SERVER['REMOTE_USER']), 2);
replaced with

Code: Select all

 list($realm,$kerbuser) = split("\\\\", strtolower($_SERVER['REMOTE_USER']), 2);
as kerberos set REMOTE_USER to username@realm and NTLM set it do realm\username

also we needed to change the dc line as although our lookup user worked across all realms the users are compartmentalised a little
so just after

Code: Select all

  // ldap_connect only checks whether the specified server is valid, so the connection might still fail
we inserted

Code: Select all

//IMH GL test stanza for setting basedn from REMOTE_USER $realm
     $dn ="";
         if (substr($_SERVER['REMOTE_USER'], 0, 4) == 'EAME')
                     {
 $dn = "OU=Users,OU=usr,OU=objects,dc=EAME,dc=COMPANY,dc=ORG";
 }
 else if (substr($_SERVER['REMOTE_USER'], 0, 4) == 'APAC')
 {
 $dn = "OU=Users,OU=usr,OU=objects,dc=APAC,dc=COMPANY,dc=ORG";
 }
 else if (substr($_SERVER['REMOTE_USER'], 0, 5) == 'NAFTA')
 {
 $dn = "OU=Users,OU=usr,OU=objects,dc=NAFTA,dc=COMPANY,dc=ORG";
 }
 else if (substr($_SERVER['REMOTE_USER'], 0, 5) == 'LATAM')
 {
 $dn = "OU=Users,OU=usr,OU=objects,dc=LATAM,dc=COMPANY,dc=ORG";
 }

Phew it's relief to get that going !
Thanks for the posting

User avatar
cedarrapidsboy
Registered User
Posts: 35
Joined: Thu Sep 29, 2005 9:45 pm

Re: [DEV] Apache/Kerberos single sign-on with LDAP/AD connection

Post by cedarrapidsboy » Wed Aug 19, 2009 9:13 pm

This mod is quite awesome. Got it working with SSPI on my Windows Apache server.

Is there any way to override the auto login? Now that you have done so much work to provide SSO, what about a user logging-in from a kiosk machine. This was obviously designed for corporate intranet users... which I represent. However, we have some machines that are logged-in via a service account (shop floor computers, conference room PCs, etc). Is there a way to logout and login as a different user?

Also, I am authenticating against a domain that is different from the computer's log-in domain. This authentication domain is supposed to have all of our accounts in it. But, what would happen if the user passed by the browser doesn't exist in the authentication domain for phpbb3? Did I just answer my own question (below):

Code: Select all

return sprintf($user->lang['LDAP_NO_IDENTITY'], $user->data['username']);
Again. Very nice work!

User avatar
cedarrapidsboy
Registered User
Posts: 35
Joined: Thu Sep 29, 2005 9:45 pm

Re: [DEV] Apache/Kerberos single sign-on with LDAP/AD connection

Post by cedarrapidsboy » Thu Aug 20, 2009 2:36 pm

Another issue I'm trying to figure out is... why does my session ID change with every page I load in the forum? I can't log into the ACP, because the session ID keeps changing.

User avatar
cedarrapidsboy
Registered User
Posts: 35
Joined: Thu Sep 29, 2005 9:45 pm

Re: [DEV] Apache/Kerberos single sign-on with LDAP/AD connection

Post by cedarrapidsboy » Thu Aug 20, 2009 2:46 pm

cedarrapidsboy wrote:Another issue I'm trying to figure out is... why does my session ID change with every page I load in the forum? I can't log into the ACP, because the session ID keeps changing.
Sorry. I had a bug in one of my modifications to this sspi code. Please disregard the session Id issue.

dzhu
Registered User
Posts: 7
Joined: Fri May 29, 2009 3:39 am

Re: [DEV] Apache/Kerberos single sign-on with LDAP/AD connection

Post by dzhu » Mon Sep 28, 2009 12:30 pm

Has anybody made single sign-on work for IIS? Thanks!

danbee
Registered User
Posts: 1
Joined: Wed Dec 02, 2009 2:41 pm

Re: [DEV] Apache/Kerberos single sign-on with LDAP/AD connection

Post by danbee » Wed Dec 02, 2009 2:45 pm

Great plugin! It works great for us with WebAuth apache authentication. Just dropped it in and it worked.

tical
Registered User
Posts: 4
Joined: Mon May 11, 2009 6:07 am

Re: [DEV] Apache/Kerberos single sign-on with LDAP/AD connec

Post by tical » Fri May 21, 2010 1:11 pm

Thanks very much for this mod. I got this installed and working on my IIS7 Windows Server 2008 R2 64-bit machine. Just had to make a small change. Instead of replacing:

Code: Select all

list($kerbuser,$realm) = split("@", strtolower($_SERVER['REMOTE_USER']), 2);
with:

Code: Select all

list($realm,$kerbuser) = split("\\\\", strtolower($_SERVER['REMOTE_USER']), 2);
I replaced it with:

Code: Select all

list($realm,$kerbuser) = split("\\\\", $_SERVER['REMOTE_USER'], 2);
strtolower was not necessary as all the usernames on our domain have proper case user names.

Thanks again.

PS: You should release this as an NTLM/LDAP mod (not Apache specific) as there are a lot of people looking for this and are probably not finding it due to references to Kerberos and Apache. Who knows, maybe phpBB may include it as a standard auth module in the next version of phpBB. ;)

TiCaL

tical
Registered User
Posts: 4
Joined: Mon May 11, 2009 6:07 am

Re: [DEV] Apache/Kerberos single sign-on with LDAP/AD connec

Post by tical » Sun Jan 16, 2011 1:37 pm

Hey krische. Got your PM but couldn't reply for some reason.

We have a special service account we use for things like this on our domain so I never actually tried the anonymous binding. I guess as long as LDAP server allows anonymous access it should work.

User avatar
tumba25
Former Team Member
Posts: 4430
Joined: Wed Jun 06, 2007 6:42 am
Location: Kokkola, Finland.
Name: Jari Kanerva
Contact:

Re: [DEV] Apache/Kerberos single sign-on with LDAP/AD connec

Post by tumba25 » Sun Jan 16, 2011 10:24 pm

Since the MOD author has not posted in this topic since 29 May 2009 I'm locking this as abandoned.

If you, the MOD author, want to continue developing you mod. Please contact a MOD team member.
Need a mod/extension created/installed, other custom-coded solution or a server admin? https://tumba25.net

Locked

Return to “[3.0.x] Abandoned MODs”