PROBLEM: We installed a great extension for connecting our Active Directory with Typo3 but we were not satisfied of how this extension works by default.
For example usergroup did not work well with our installation and this blocked the update of existing users linked to internal groups so we changed it as follows:
File: mod1/index.php
<?php
/***************************************************************
* Copyright notice
*
* (c) 2003 Norman Seibert (seibert@entios.de)
* All rights reserved
*
* This script is part of the Typo3 project. The Typo3 project is
* free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* The GNU General Public License can be found at
* http://www.gnu.org/copyleft/gpl.html.
*
* This script is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* This copyright notice MUST APPEAR in all copies of the script!
***************************************************************/
/**
* Module 'LDAP Integration' for the 'eu_ldap' extension.
*
* @author Norman Seibert <seibert@entios.de>
*/
// DEFAULT initialization of a module [BEGIN]
unset($MCONF);
require ('conf.php');
require_once ('class.tx_euldap_div.php');
require ($BACK_PATH.'init.php');
require ($BACK_PATH.'template.php');
include ('locallang.php');
require_once (PATH_t3lib.'class.t3lib_scbase.php');
$BE_USER->modAccess($MCONF, 1);
// This checks permissions and exits if the users has no permission for entry.
// DEFAULT initialization of a module [END]
class tx_euldap_module1 extends t3lib_SCbase {
var $pageinfo;
/**
* @return [type] ...
*/
function init() {
global $AB, $BE_USER, $LANG, $BACK_PATH, $TCA_DESCR, $TCA, $HTTP_GET_VARS,
$HTTP_POST_VARS, $CLIENT, $TYPO3_CONF_VARS;
parent::init();
/*
if (t3lib_div::GPvar('clear_all_cache')) {
$this->include_once[]=PATH_t3lib.'class.t3lib_tcemain.php';
}
*/
}
/**
* Adds items to the->MOD_MENU array. Used for the function menu selector.
*
* @return [type] ...
*/
function menuConfig() {
global $LANG;
$this->MOD_MENU = Array (
'function' => Array (
'1' => $LANG->getLL('function1'),
'2' => $LANG->getLL('function2'),
'3' => $LANG->getLL('function3'),
'4' => $LANG->getLL('function4'),
'5' => $LANG->getLL('function5'),
'6' => $LANG->getLL('function6'),
'7' => $LANG->getLL('function7'),
)
);
parent::menuConfig();
}
// If you chose "web" as main module, you will need to consider the $this->id
parameter which will contain the uid-number of the page clicked in the page tree
/**
* Main function of the module. Write the content to $this->content
*
* @return [type] ...
*/
function main() {
global $AB, $BE_USER, $LANG, $BACK_PATH, $TCA_DESCR, $TCA, $HTTP_GET_VARS,
$HTTP_POST_VARS, $CLIENT, $TYPO3_CONF_VARS;
// Access check!
// The page will show only if there is a valid page and if this page may be
viewed by the user
$this->pageinfo = t3lib_BEfunc::readPageAccess($this->id, $this->perms_clause);
$access = is_array($this->pageinfo) ? 1 :
0;
if (($this->id && $access) || ($BE_USER->user['admin'] && !$this->id)) {
// Draw the header.
$this->doc = t3lib_div::makeInstance('mediumDoc');
$this->doc->backPath = $BACK_PATH;
$this->doc->form = '<form action="" method="POST">';
// JavaScript
$this->doc->JScode = '
<script language="javascript">
script_ended = 0;
function jumpToUrl(URL) {
document.location = URL;
}
</script>
';
$this->doc->postCode = '
<script language="javascript">
script_ended = 1;
if (top.theMenu) top.theMenu.recentuid = '.intval($this->id).';
</script>
';
$headerSection = $this->doc->getHeader('pages', $this->pageinfo,
$this->pageinfo['_thePath']).'<br>'.$LANG->php3Lang['labels']['path'].':
'.t3lib_div::fixed_lgd_pre($this->pageinfo['_thePath'], 50);
$this->content .= $this->doc->startPage($LANG->getLL('title'));
$this->content .= $this->doc->header($LANG->getLL('title'));
$this->content .= $this->doc->spacer(5);
$this->content .= $this->doc->section('', $this->doc->funcMenu($headerSection,
t3lib_BEfunc::getFuncMenu($this->id, 'SET[function]',
$this->MOD_SETTINGS['function'], $this->MOD_MENU['function'])));
$this->content .= $this->doc->divider(5);
// Render content:
$this->moduleContent();
// ShortCut
if ($BE_USER->mayMakeShortcut()) {
$this->content .= $this->doc->spacer(20).$this->doc->section('',
$this->doc->makeShortcutIcon('id', implode(',', array_keys($this->MOD_MENU)),
$this->MCONF['name']));
}
$this->content .= $this->doc->spacer(10);
} else {
// If no access or if ID == zero
$this->doc = t3lib_div::makeInstance('mediumDoc');
$this->doc->backPath = $BACK_PATH;
$this->content .= $this->doc->startPage($LANG->getLL('title'));
$this->content .= $this->doc->header($LANG->getLL('title'));
$this->content .= $this->doc->spacer(5);
$this->content .= $this->doc->spacer(10);
}
}
/**
* Prints out the module HTML
*
* @return [type] ...
*/
function printContent() {
global $SOBE;
$this->content .= $this->doc->middle();
$this->content .= $this->doc->endPage();
echo $this->content;
}
/**
* [Describe function...]
*
* @return [type] ...
*/
function moduleContent() {
global $LANG, $HTTP_POST_VARS;
// debug($GLOBALS['HTTP_GET_VARS']);
// debug($GLOBALS['HTTP_POST_VARS']);
tx_euldap_div::initChar('');
$doCommand = false;
$dbres = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
'count(*) as cnt',
'tx_euldap_server',
'pid IN ('.$this->id.')'
);
$row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($dbres);
if ($row['cnt']) {
if ($HTTP_POST_VARS['submit']) {
$doCommand = true;
} else {
$this->content .= '<input type="submit" name="submit"
value="'.$LANG->getLL('submit').'" />';
}
} else {
$this->content .= $LANG->getLL('no_servers');
}
if ($doCommand && $this->id) {
switch((string)$this->MOD_SETTINGS['function']) {
case 1: //summary
// Frontend-Users
$dbres = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
'count(*)',
'fe_users',
'NOT deleted AND pid = '.$this->id
);
if ($dbres) $row = $GLOBALS['TYPO3_DB']->sql_fetch_row($dbres);
$content = '<div>'.$row[0].' '.$LANG->getLL('users').'</div>';
$this->content .= $this->doc->section('Frontend:', $content, 0, 1);
// Backend-Users
$dbres = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
'count(*)',
'be_users',
'NOT deleted'
);
if ($dbres) $row = $GLOBALS['TYPO3_DB']->sql_fetch_row($dbres);
$content = '<div>'.$row[0].' '.$LANG->getLL('users').'</div>';
$this->content .= $this->doc->section('Backend:', $content, 0, 1);
// LDAP
$dbres = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
'*',
'tx_euldap_server',
'pid IN ('.$this->id.')'
);
while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($dbres)) {
$ldapserver = $row['server'];
$ldapres = tx_euldap_div::search_ldap($row, '*');
$content = '<div>'.$ldapres['count'].' '.$LANG->getLL('users').'</div>';
$this->content .= $this->doc->section($ldapserver.":", $content, 0, 1);
}
break;
case 2: //update FE-users
$content = $this->index_update_users('fe', $this->id);
$this->content .= $this->doc->section($LANG->getLL('users').":", $content, 0,
1);
break;
case 5: //update BE-users
//$content = $this->index_update_users('be', 0, $this->id);
$content = $this->index_update_users('be', 0);
$this->content .= $this->doc->section($LANG->getLL('users').":", $content, 0,
1);
break;
case 3: //import FE-users
$content = $this->index_import_users('fe', $this->id);
$this->content .= $this->doc->section($LANG->getLL('new').'
'.$LANG->getLL('users').":", $content, 0, 1);
break;
case 6: //import BE-users
$content = $this->index_import_users('be', 0);
$this->content .= $this->doc->section($LANG->getLL('new').'
'.$LANG->getLL('users').":", $content, 0, 1);
break;
case 4: //delete FE-users
$content = $this->index_delete_users('fe_users', $this->id);
$this->content .= $this->doc->section($LANG->getLL('deleted').'
'.$LANG->getLL('users').":", $content, 0, 1);
break;
case 7: //delete BE-users
$content = $this->index_delete_users('be_users', 0);
$this->content .= $this->doc->section($LANG->getLL('deleted').'
'.$LANG->getLL('users').":", $content, 0, 1);
break;
}
}
}
/**
* [Describe function...]
*
* @param [type] $user_prefix: ...
* @param [type] $pid: ...
* @return [type] ...
*/
function index_update_users($user_prefix, $pid) {
global $LANG;
tx_euldap_div::initChar('');
$dbres = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
'uid, title',
$user_prefix.'_groups',
sprintf('deleted = 0 AND hidden = 0 %s', ($this->checkPid?' AND pid =
'.$this->checkPid_value:''))
);
while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($dbres)) {
$arrGroups[] = $row;
}
// load users
$res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
'*',
$user_prefix.'_users',
'NOT deleted AND pid = '.$pid
);
// LDAP
$dbres = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
'*',
'tx_euldap_server',
($this->id?'pid IN ('.$this->id.') AND ':'')
.'authenticate_be IN
('.($user_prefix=='fe'?'0,':'').($user_prefix=='be'?'1,':'').'2)'
);
while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($dbres)) {
$arrServers[] = $row;
}
unset($dbres);
$content = $LANG->getLL('rownumber_limit').'<table cellpadding=0 cellspacing=0
border=0>
<tr>
<td nowrap><b>'.$LANG->getLL('account').'</b></td>
<td> </td>
<td nowrap><b>'.$LANG->getLL('name').'</b></td>
<td> </td>
<td nowrap><b>'.$LANG->getLL('group').'</b></td>
<td> </td>
<td nowrap><b>'.$LANG->getLL('email').'</b></td>
<td> </td>
<td nowrap><b>'.$LANG->getLL('ldap').'</b></td>
</tr>';
$i = 0;
while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
//t3lib_div::debug($row['username']);
$arrDisplay = tx_euldap_div::update_user($arrServers, $arrGroups,
$row['username'], $user_prefix.'_users', $this->id);
if ($arrDisplay && ($i < 100000)) {
$i++;
$content .= '<tr>
<td nowrap>'.$row['username'].'</td>
<td></td>
<td nowrap>'.$arrDisplay['name'].'</td>
<td></td>
<td nowrap>'.$arrDisplay['gname'].'</td>
<td></td>
<td nowrap>'.$arrDisplay['email'].'</td>
<td></td>
<td nowrap>'.$arrDisplay['ldapserver'].'</td>
</tr>';
}
}
$content .= '</table>';
return $content;
}
/**
* [Describe function...]
*
* @param [type] $user_prefix: ...
* @param [type] $pid: ...
* @return [type] ...
*/
function index_import_users($user_prefix, $pid) {
global $LANG;
tx_euldap_div::initChar('');
srand((double)microtime() * 1000000);
//load groups
$dbres = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
'uid, title',
$user_prefix.'_groups',
sprintf('deleted = 0 AND hidden = 0 %s', ($this->checkPid?' AND pid =
'.$this->checkPid_value:''))
);
while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($dbres)) {
$arrGroups[] = $row;
}
// LDAP
$dbres = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
'*',
'tx_euldap_server',
($this->id?'pid IN ('.$this->id.') AND ':'')
.'authenticate_be IN
('.($user_prefix=='fe'?'0,':'').($user_prefix=='be'?'1,':'').'2)'
);
while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($dbres)) {
$arrServers[] = $row;
}
$content = '<table cellpadding=0 cellspacing=0 border=0>
<tr>
<td><b>'.$LANG->getLL('account').'</b></td>
<td> </td>
<td><b>'.$LANG->getLL('name').'</b></td>
<td> </td>
<td><b>'.$LANG->getLL('group').'</b></td>
<td> </td>
<td><b>'.$LANG->getLL('email').'</b></td>
<td> </td>
<td><b>'.$LANG->getLL('ldap').'</b></td>
</tr>';
$i = 0;
while ($i < count($arrServers)) {
$content .= tx_euldap_div::import_users($pid, $arrServers[$i], $arrGroups,
$user_prefix.'_users');
$i++;
}
$content .= '</table>';
return $content;
}
/**
* [Describe function...]
*
* @param [type] $user_table: ...
* @param [type] $pid: ...
* @return [type] ...
*/
function index_delete_users($user_table, $pid) {
global $LANG;
tx_euldap_div::initChar('');
// load users
$res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
'*',
$user_table,
'pid = '.$pid.' AND deleted = 0'
);
// LDAP
$dbres = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
'*',
'tx_euldap_server',
($this->id?'pid IN ('.$this->id.') AND ':'')
.'authenticate_be IN
('.($user_table=='fe_users'?'0,':'').($user_table=='be_users'?'1,':'').'2)'
);
while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($dbres)) {
$arrServers[] = $row;
}
$content = '<table cellpadding=0 cellspacing=0 border=0>
<tr>
<td><b>'.$LANG->getLL('account').'</b></td>
<td> </td>
<td><b>'.$LANG->getLL('email').'</b></td>
</tr>';
while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
$display = tx_euldap_div::delete_user($arrServers, $row, $user_table);
if ($display) {
$content .= '<tr>
<td nowrap>'.$row['username'].'</td>
<td></td>
<td nowrap>'.$row['email'].'</td>
</tr>';
}
}
$content .= '</table>';
return $content;
}
}
if (defined('TYPO3_MODE') &&
$TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/eu_ldap/mod1/index.php']) {
include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/eu_ldap/mod1/index.php']);
}
// Make instance:
$SOBE = t3lib_div::makeInstance('tx_euldap_module1');
$SOBE->init();
// Include files?
reset($SOBE->include_once);
while (list(, $INC_FILE) = each($SOBE->include_once)) {
include_once($INC_FILE);
}
$SOBE->main();
$SOBE->printContent();
?>
File mod1/class.tx_euldap_div.php :
<?php
/***************************************************************
* Copyright notice
*
* (c) 2003 Norman Seibert (seibert@entios.de)
* All rights reserved
*
* This script is part of the Typo3 project. The Typo3 project is
* free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* The GNU General Public License can be found at
* http://www.gnu.org/copyleft/gpl.html.
*
* This script is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* This copyright notice MUST APPEAR in all copies of the script!
***************************************************************/
/**
* Class for searching ldap-tree, import, update and authentificate
* users and groups.
*
* @author Norman Seibert <seibert@entios.de>
*/
/**
* [CLASS/FUNCTION INDEX of SCRIPT]
*
*
*
* 60: class tx_euldap_div
* 69: function search_ldap($server_info,$findname)
* 108: function additional_fields($map_additional_fields,$ldapres)
* 130: function use_memberof($servertype)
* 156: function is_in_onlygroups($onlygroup, $groupnamelist)
* 190: function assign_groups($Server, $arrGroups, $ldapres, &$gid, &$gname,
$table, $pid)
* 341: function insert_newgrps($table, $grps, $match, $pid)
* 390: function update_user($arrServers, $arrGroups, $username, $user_table,
$pid)
* 437: function update_singleuser($Server, $arrGroups, $user, $user_table, $pid)
* 515: function import_users($pid, $arrServer, $arrGroups, $user_table)
* 534: function import_singleuser($arrGroups, $user, $Server, $pid, $user_table,
$return=false)
* 647: function delete_user($arrServers, $row, $user_table, $delete=true)
* 690: function checkNTUser ($server_info,$username,$password)
*
* TOTAL FUNCTIONS: 13
* (This index is automatically created/updated by the extension "extdeveval")
*
*/
/**
* Class for searching ldap-tree, import, update and authentificate
* users and groups.
*
* @author Norman Seibert <seibert@entios.de>
*/
class tx_euldap_div {
var $csObj;
var $remoteChar;
var $localChar;
var $conf;
function tx_euldap_div() {
global $TYPO3_CONF_VARS;
$this->conf = unserialize($TYPO3_CONF_VARS['EXT']['extConf']['eu_ldap']);
$this->initChar('');
}
/**
* Sets the character sets.
*
*
* @return void
*/
function initChar($charset) {
global $TYPO3_CONF_VARS;
if ((isset($GLOBALS['TSFE'])) && (isset($GLOBALS['TSFE']->csConvObj))) {
$this->csObj = $GLOBALS['TSFE']->csConvObj;
} else {
if(!class_exists('t3lib_cs') && defined('PATH_t3lib')) {
require_once(PATH_t3lib.'class.t3lib_cs.php');
}
$this->csObj = t3lib_div::makeInstance('t3lib_cs');
}
$this->remoteChar = $this->csObj->parse_charset($charset ? $charset : 'utf-8');
$this->localChar =
$this->csObj->parse_charset($TYPO3_CONF_VARS['BE']['forceCharset'] ?
$TYPO3_CONF_VARS['BE']['forceCharset'] : 'iso-8859-1');
}
/**
* Gets object from ldap tree if the given findname can be found.
*
* @param array $server_info: containing all server information + filter to do
the search
* @param string $findname: username to look for
* @return array all ldap entries for user or false
*/
function search_ldap($server_info,$findname) {
//debug($server_info);
if ($findname) {
//
// convert character set local -> remote
$findname = $this->csObj->conv($findname, $this->localChar, $this->remoteChar);
$server = $server_info['server'];
$port = $server_info['port'];
$version = $server_info['version'];
$auth_user = $server_info['user'];
$auth_pass = $server_info['password'];
$base_dn = $server_info['base_dn'];
$strfilter = $server_info['filter'];
$servertype = $server_info['servertype'];
$filter = str_replace('<search>', $findname, $strfilter);
if(!extension_loaded('ldap')) die('Your PHP version seems to lack LDAP support.
Please install.');
if (!($connect = @ldap_connect($server, $port))) die('Could not connect to ldap
server '.$server);
if ($version == 3) {
@ldap_set_option($connect, LDAP_OPT_PROTOCOL_VERSION, 3);
if ($servertype == 1) ldap_set_option($connect, LDAP_OPT_REFERRALS, 0);
}
if (substr(strtolower($server), 0, 8) == 'ldaps://') {
if (!function_exists( 'ldap_start_tls' )) die('Function ldap_start_tls not
available.');
@ldap_start_tls($connect);
}
@ldap_set_option($connect, LDAP_OPT_REFERRALS, 0);
if (!($bind = @ldap_bind($connect, $auth_user, $auth_pass))) die('Unable to bind
to server '.$server);
if (!($search = @ldap_search($connect, $base_dn, $filter))) die('Unable to
search ldap server '.$server);
$info = ldap_get_entries($connect, $search);
// convert character set remote -> local
if (is_array($info)) $info = tx_euldap_div::convertArray($info,
$this->remoteChar, $this->localChar);
//t3lib_div::debug($info);
// t3lib_div::debug($findname);
// if ($findname == "mbozzano" or $findname == "twolday")
{t3lib_div::debug($info);}
return $info;
}
}
/**
* If additional fields should be importet, this function returns the needed
Strings for DB-Insert Operation
*
* @param string $map_additional_fields:
tablefield0=ldapAttr0,tablefield1=ldapAttr1,...
* @param array $ldapres: result of ldapquery (attributes in first dimension!)
($ldapres[attribute])
* @param string $TYP: ["UPDATE"|"INSTERT"] //OBSOLETE!!
* @return array array of field => value
* @todo must return array of field/value to use DBAL
*/
function additional_fields($map_additional_fields,$ldapres) {
if ($map_additional_fields !="") {
$pairs=explode(',',$map_additional_fields);
$insertArray=array(); //initialise array...
foreach ($pairs as $value) {
list($tablekey, $ldapkey)=explode("=",$value);
$ldapkey=strtolower(trim($ldapkey));
$tablekey=strtolower(trim($tablekey));
if (is_array($ldapres[$ldapkey])) {
$insertArray[$tablekey]= str_replace("'", "''", $ldapres[$ldapkey][0]);
}
}
}
return $insertArray;
}
/**
* [Function returns the needed String for the Attribut Memberof. Because it is
diffrent in diffrent LDAP-Servertypes]
*
* @param [type] $servertype: ...
* @return [type] ...
*/
function use_memberof($servertype) {
switch($servertype) {
case 0:
$use_memberOf = 'memberof';
break;
case 1:
$use_memberOf = 'memberof';
break;
case 2:
$use_memberOf = 'groupmembership';
break;
case 3:
$use_memberOf = 'posixGroup';
break;
}
return $use_memberOf;
}
/**
* [Function test if User is in one of the specified groups (only_groups)]
*
* @param [comma seperated string] $onlygroup: ...
* @param [comma seperated string] $groupnamelist: ...
* @return [type] ...
*/
function is_in_onlygroups($onlygroup, $groupnamelist) {
//No Group is selected then all users allowed
if ($onlygroup == "") {
return 1;
}
$onlygrouparray = explode(",",$onlygroup);
$grouparray = explode(",",$groupnamelist);
for ($k=0; $k < count($grouparray); $k++) {
$group = $grouparray[$k];
foreach ($onlygrouparray as $value) {
$value=strtolower(trim($value));
$regExpr = str_replace("?", ".", str_replace("*", ".*", "/^".$value."$/"));
if (preg_match($regExpr, strtolower($group))) return 1;
}
}
return 0;
}
/**
* assigns ldap and typo3 groups. LDAP groups can be imported if flag is set
*
* @param boolean $use_memberOf: use the memberOf attribute
* @param array $arrGroups: array with typo3-groups (fe/be)
* @param array $ldapres: ldap attributes and values
* @param string $ldapbuildgroup: how to match the typo groups
* @param int eger $gid: groupids, output parameter
* @param string $gname:groupnames, output parameter
* @param string $match: import only groups begining with this string
* @param string $addnewgroups: if set groups are imported/created
* @param string $table: fe_users or be_users
* @param integer $pageID for the group
* @return void - uses refvars gid and gname
*/
function assign_groups($Server, $arrGroups, $ldapres, &$gid, &$gname, $table,
$pid) {
$ldapbuildgroup = $Server['build_group'];
$use_memberOf = $Server['memberof'];
$match = $Server['matchgrps'];
$servertype = $Server['servertype'];
$memberOf = tx_euldap_div::use_memberOf($servertype);
$addnewgroups = $Server['doitfe'];
$fe_groups = $Server['fe_group'];
$be_groups = $Server['be_group'];
if (''.$use_memberOf != '0') {
$k = 0;
$gid = '';
$department = '';
$gname = '';
if ($memberOf == 'posixGroup') {
$uid = $ldapres['uid'][0];
/* change the filterstring for searching groups */
// $Server['filter'] = "(&(objectclass=posixGroup)(memberUid=<search>))";
$Server['filter'] =
"(&(objectclass=posixGroup)(|(memberUid=<search>)(gidNumber=" .
$ldapres['gidnumber'][0] . ")))";
$group_info = tx_euldap_div::search_ldap($Server, $uid);
while ($k < $group_info['count']) {
if (is_array($group_info[$k]['cn'])) {
$department = $group_info[$k]['cn'][0];
} else {
$department = $group_info[$k]['cn'];
}
if ($department) {
$j = 0;
$group_found = false;
while (($j < sizeof($arrGroups)) && !($group_found)) {
if (strtolower($arrGroups[$j]['title']) == strtolower($department)) {
$group_found = true;
if (tx_euldap_div::is_in_onlygroups($Server['matchgrps'],
$arrGroups[$j]['title'])) {
$gid .= ','.$arrGroups[$j]['uid'];
$gname .= ','.$arrGroups[$j]['title'];
}
}
$j++;
}
if (!$group_found && tx_euldap_div::is_in_onlygroups($Server['matchgrps'],
$department)) $newgroups[] = $department;
}
$k++;
}
} else {
while ($k < count($ldapres[$memberOf])) {
$department = $ldapres[$memberOf][$k];
$equal = strpos($department, 'cn=');
$comma = strpos($department, ',', $equal);
$department = substr($department, $equal+3, $comma-$equal-3);
if ($department) {
$j = 0;
$group_found = false;
while (($j < sizeof($arrGroups)) && !($group_found)) {
if (strtolower($arrGroups[$j]['title']) == strtolower($department)) {
$group_found = true;
if (tx_euldap_div::is_in_onlygroups($Server['matchgrps'],
$arrGroups[$j]['title'])) {
$gid .= ','.$arrGroups[$j]['uid'];
$gname .= ','.$arrGroups[$j]['title'];
}
}
$j++;
}
if (!$group_found && tx_euldap_div::is_in_onlygroups($Server['matchgrps'],
$department)) $newgroups[] = $department;
}
$k++;
}
}
} else {
$department = $ldapbuildgroup;
while (ereg('<([^>]*)>', $department, $arrMatches)) {
if ((strtolower($arrMatches[1]) != 'ou') &&
(is_array($ldapres[$arrMatches[1]]))) {
$gid = '';
$gname = '';
$jjj=0;
while(($jjj < count($ldapres[$arrMatches[1]])-1)){
$department = $ldapbuildgroup;
$found = $ldapres[$arrMatches[1]][$jjj];
$department = str_replace('<'.$arrMatches[1].'>', $found, $department);
$j = 0;
$group_found = false;
while (($j < sizeof($arrGroups)) && !($group_found)) {
if (strtolower($arrGroups[$j]['title']) == strtolower($department)) {
$group_found = true;
if (tx_euldap_div::is_in_onlygroups($Server['matchgrps'], $gname)) {
$gid.= ','.$arrGroups[$j]['uid'];
$gname.= ','.$arrGroups[$j]['title'];
}
}
$j++;
}
if (!$group_found && tx_euldap_div::is_in_onlygroups($Server['matchgrps'],
$department)) $newgroups[] = $department;
$jjj++;
}
} else {
$gid = '';
$gname = '';
if (is_array($ldapres['dn'])) {
$dn = $ldapres['dn'][0];
} else {
$dn = $ldapres['dn'];
}
$arrDN = explode(",", $dn);
for ($jj=0; $jj < count($arrDN); $jj++) {
$arrKeys = explode("=", $arrDN[$jj]);
if (strtolower($arrKeys[0]) == strtolower($arrMatches[1])) {
$found = $arrKeys[1];
$tmpdepartment = str_replace('<'.$arrMatches[1].'>', $found, $department);
$j = 0;
$group_found = false;
while (($j < count($arrGroups)) && !($group_found)) {
if (strtolower($arrGroups[$j]['title']) == strtolower($tmpdepartment)) {
$group_found = true;
$gid.= ','.$arrGroups[$j]['uid'];
$gname.= ','.$arrGroups[$j]['title'];
}
$j++;
}
(!$group_found)?$newgroups[]=$department:'';
}
}
$department = $tmpdepartment;
}
}
}
if ((is_array($newgroups)) && ($addnewgroups)) {
reset($newgroups);
$newgrouparray = tx_euldap_div::insert_newgrps($table, $newgroups, $match,
$pid);
if (is_array($newgrouparray)) {
reset($newgrouparray);
foreach ($newgrouparray as $newgrpid => $newgrpname) {
if ($newgrpname != '') {
$gid.=','.$newgrpid;
$gname.=','.$newgrpname;
}
}
}
}
if (($table == 'fe_users') && $fe_groups) $gid .= ','.$fe_groups;
if (($table == 'be_users') && $be_groups) $gid .= ','.$be_groups;
// cuts of leading ','
if ($gid) $gid = substr($gid, 1);
if ($gname) $gname = substr($gname, 1);
}
/**
* Insert new groups into the table (fe or be)
*
* @param string $table: be or fe groups table
* @param array $grps: groupnames of unmatched groupes
* @param string $match: matchstring; must match the beginning of string
* @param integer $pid: pageID for group
* @return array key:groupId of new group, value=groupname
*/
function insert_newgrps($table, $grps, $match, $pid) {
if ($table == 'be_users') {
$pid = 0;
$table = 'be_groups';
} else {
$table = 'fe_groups';
}
foreach ($grps as $grp) {
$qry = Array(
'pid' => $pid,
'tstamp' => time(),
'title' => $grp,
'description' => 'Inserted by eu_ldap '.time(),
'eu_ldap' => '1'
);
//match condition at beginning of group
$bolCreate = true;
if ($match) $bolCreate = false;
$onlygrouparray = explode(",", $match);
foreach ($onlygrouparray as $value) {
$value = strtolower(trim($value));
$regExpr = str_replace("?", ".",
str_replace("*", ".*", "/^".$value."$/"));
if (preg_match($regExpr, strtolower($grp))) $bolCreate = true;
}
if ($bolCreate) {
$rslt = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
'uid, title',
$table,
"title = '".$grp."' AND hidden = 0 AND deleted = 0"
);
if ($rslt) $row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($rslt);
if(!$row) {
$dbres = $GLOBALS['TYPO3_DB']->exec_INSERTquery($table, $qry);
$rslt = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
'uid, title',
$table,
"title='".$grp."'"
);
if ($rslt) $row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($rslt);
}
$return[$row['uid']] = $row['title'];
}
}
return $return;
}
/**
* Updates typo3 users with data from ldap user object
*
* @param array $arrServers: information about ldap servers to query
* @param array $arrGroups: existing typo3 groups (fe/be)
* @param string $username: username of user to update
* @param string $user_table: fe_users or be_users
* @param integer $pid: pageID; necessary for automatic creation of groups
* @return string with information about updated user or FALSE if user does not
exist in ldap
*/
function update_user($arrServers, $arrGroups, $username, $user_table, $pid) {
$i = 0;
$user_found = false;
while (($i < count($arrServers)) && !($user_found)) {
$ldapres = tx_euldap_div::search_ldap($arrServers[$i],$username);
//t3lib_div::debug($ldapres[1]);
//die();
/* if ($ldapres['count'] > 1) {
while (($jj <= $ldapres['count'])) {
// use update_single_user from here..
$arrDisplay =
tx_euldap_div::update_singleuser($arrServers[$i],$arrGroups,$ldapres[$jj],$user_table,$pid);
$jj++;
}
$user_found = true;
return $arrDisplay;
}
*/
if ($ldapres['count'] == 1) {
// use update_single_user from here..
$arrDisplay =
tx_euldap_div::update_singleuser($arrServers[$i],$arrGroups,$ldapres[0],$user_table,$pid);
$user_found = true;
return $arrDisplay;
}
$i++;
}
if (!$user_found) return false;
}
/**
* updates single user (see above)
* does not return anything at all
*
* @param array $Server: row with ldap-server settings
* @param array $arrGroups: array of groups (fe/be)
* @param array $user: user to be updated (ldap attribute array)
* @param string $user_table: fe_users or be_users
* @param integer $pid: pageID; necessary for automatic creation of groups
* @return void nothing at all..
*/
function update_singleuser($Server, $arrGroups, $user, $user_table, $pid) {
$ldapserver = $Server['server'];
$ldapname = $Server['name'];
$ldapusername = $Server['username'];
$ldapmail = $Server['mail'];
$ldapphone = $Server['phone'];
$ldapfax = $Server['fax'];
$ldapaddress = $Server['address'];
$ldapzip = $Server['zip'];
$ldapcity = $Server['city'];
$ldapcountry = $Server['country'];
$ldapwww = $Server['www'];
$ldapbuildgroup = $Server['build_group'];
$use_memberOf = $Server['memberof'];
$map_additional_fields = $Server['map_additional_fields'];
if ($use_memberOf) $use_memberOf =
tx_euldap_div::use_memberof($Server['servertype']);
switch($Server['servertype']) {
case 0:
$username = $user['samaccountname'][0];
break;
case 1:
$username = $user['samaccountname'][0];
break;
case 2:
case 3:
$username = $user[$ldapusername][0];
break;
}
$name = $user[$ldapname][0];
$email = $user[$ldapmail][0];
$GLOBALS['TYPO3_DB']->debugOutput = TRUE;
if ($ldapbuildgroup || $use_memberOf) tx_euldap_div::assign_groups($Server,
$arrGroups, $user, $gid, $gname, $user_table, $pid);
// preserve groups not imported by eu_ldap
$dbres = $GLOBALS['TYPO3_DB']->exec_SELECTquery ('uid',
($user_table=='fe_users'?'fe_groups':'be_groups'), 'eu_ldap = 0 AND uid IN
(SELECT usergroup FROM '.$user_table." WHERE lower(username) =
'".strtolower($GLOBALS['TYPO3_DB']->quoteStr($username,$user_table))."')");
// t3lib_div::debug($name. " ".$email."<br/>");
while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($dbres)) {
$gid .= ', '.$row['uid'];
}
if ($user_table == 'fe_users') {
$map_additional_fields =
'address='.$ldapaddress
.',zip='.$ldapzip
.',city='.$ldapcity
.',country='.$ldapcountry
.',address='.$ldapaddress
.',telephone='.$ldapphone
.',fax='.$ldapfax
.',www='.$ldapwww
.($map_additional_fields?','.$map_additional_fields:'');
$updateArray = array('tstamp' => time(),
'name' => str_replace("'", "''", $name),
'email' => $email
);
// if ($ldapbuildgroup || $use_memberOf) $updateArray['usergroup'] = $gid;
} else {
$updateArray = array('tstamp' => time(),
'email' => $email,
'realname' => str_replace("'", "''", $name)
);
// if ($ldapbuildgroup || $use_memberOf) $updateArray['usergroup'] = $gid;
$updateArray['fileoper_perms'] = '1';
}
$map_additional_fields_up =
tx_euldap_div::additional_fields($map_additional_fields, $user);
if (is_array($map_additional_fields_up) and ($user_table == 'fe_users'))
$updateArray = t3lib_div::array_merge($updateArray, $map_additional_fields_up);
//if
(strtolower($GLOBALS['TYPO3_DB']->quoteStr($username,$user_table))=='mbozzano')
t3lib_div::debug($updateArray);
if ($user_table == 'be_users') {
$pippo=$GLOBALS['TYPO3_DB']->exec_UPDATEquery($user_table,"lower(username) =
'".strtolower($GLOBALS['TYPO3_DB']->quoteStr($username,$user_table))."' AND
pid=0",$updateArray);
t3lib_div::debug(strtolower($GLOBALS['TYPO3_DB']->quoteStr($username,$user_table)).'
'.$pippo);
}
else {
$pippo= $GLOBALS['TYPO3_DB']->exec_UPDATEquery($user_table,"lower(username) =
'".strtolower($GLOBALS['TYPO3_DB']->quoteStr($username,$user_table))."' AND
pid=".$pid,$updateArray);
}
//t3lib_div::debug($map_additional_fields_up);
$arrDisplay['name'] = $name;
$arrDisplay['gname'] = $gname;
$arrDisplay['email'] = $email;
$arrDisplay['ldapserver'] = $ldapserver;
//t3lib_div::debug($arrDisplay);
return $arrDisplay;
}
/**
* imports users from ldap-tree
*
* @param integer $pid: page id where userdata is stored
* @param array $arrServer: array with server information
* @param array $arrGroups: array of typo3 groups
* @param string $user_table: fe_users or be_users
* @return string html content with results
*/
function import_users($pid, $arrServer, $arrGroups, $user_table) {
$ldapres = tx_euldap_div::search_ldap($arrServer, '*');
for ($l=0; $l<$ldapres['count']; $l++) {
$content .=
tx_euldap_div::import_singleuser($arrGroups,$ldapres[$l],$arrServer,$pid,$user_table,1);
}
return $content;
}
/**
* imports a single user into table. Needed for automtic import after successfull
login
*
* @param array $arrGroups: typo groups
* @param array $user: uset to be inserted
* @param array $Server: server information (ldap)
* @param integer $pid: pid of user storage page
* @param string $user_table: fe_users or be_users
* @param boolean $return: should html-output be generated?
* @return string boolean if $return = false or html-table
*/
function import_singleuser($arrGroups, $user, $Server, $pid, $user_table,
$return=false) {
$OK = false;
$ldapserver = $Server['server'];
$ldapname = $Server['name'];
$ldapusername = $Server['username'];
$ldapmail = $Server['mail'];
$ldapphone = $Server['phone'];
$ldapfax = $Server['fax'];
$only_emailusers = $Server['only_emailusers'];
$ldapaddress = $Server['address'];
$ldapzip = $Server['zip'];
$ldapcity = $Server['city'];
$ldapcountry = $Server['country'];
$ldapwww = $Server['www'];
$use_memberOf = $Server['memberof'];
$map_additional_fields = $Server['map_additional_fields'];
if ($use_memberOf) $use_memberOf =
tx_euldap_div::use_memberof($Server['servertype']);
switch($Server['servertype']) {
case '0':
$username = $user['samaccountname'][0];
break;
case '1':
$username = $user['samaccountname'][0];
break;
case '2':
$username = $user[$ldapusername][0];
break;
case '3':
$username = $user[$ldapusername][0];
break;
}
$query = (($pid)?'pid ='.$pid.' AND ':'')."NOT deleted AND lower(username) =
'".$GLOBALS['TYPO3_DB']->quoteStr(strtolower($username),$user_table)."'";
$res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('email', $user_table, $query);
$row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res);
if (!is_array($row) && ($username != '')){
$name = $user[$ldapname][0];
$email = $user[$ldapmail][0];
$telephone = $user[$ldapphone][0];
$ldapbuildgroup = $Server['build_group'];
if (($email) || !($only_emailusers)) {
if ($ldapbuildgroup || $use_memberOf) tx_euldap_div::assign_groups($Server,
$arrGroups, $user, $gid, $gname, $user_table, $pid);
$show = false;
if ($Server['matchgrps']) {
if ($gname) $show = true;
} else {
$show = true;
}
if ($show) {
$password = '';
$content.= '<tr>
<td>'.$username.'</td>
<td> </td>
<td>'.$name.'</td>
<td> </td>
<td>'.$gname.'</td>
<td> </td>
<td>'.$email.'</td>
<td> </td>
<td>'.$ldapserver.'</td>
</tr>';
srand ((double)microtime()*1000000);
for ($l=1;$l<11;$l++) {
$rand_num = round(rand(1, 26) + 97, 0);
$password.= chr($rand_num);
}
$insValues=array('crdate' => time(),
'tstamp' => time(),
'pid'=> $pid,
'username' => str_replace("'", "''", $username),
'email' => $email,
'password' => $password
);
if ($ldapbuildgroup || $use_memberOf) $insValues['usergroup'] = $gid;
if ($user_table == 'fe_users') {
$insValues['address'] = str_replace("'", "''", $user[$ldapaddress][0]);
$insValues['zip'] = str_replace("'", "''", $user[$ldapzip][0]);
$insValues['city'] = str_replace("'", "''", $user[$ldapcity][0]);
$insValues['country'] = str_replace("'", "''", $user[$ldapcountry][0]);
$insValues['www'] = str_replace("'", "''", $user[$ldapwww][0]);
$insValues['telephone'] = str_replace("'", "''", $telephone);
$insValues['fax'] = str_replace("'", "''", $user[$ldapfax][0]);
$insValues['name'] = str_replace("'", "''", $name);
} else {
$insValues['options'] = '3';
$insValues['realname'] = str_replace("'", "''", $name);
}
$mapArray = tx_euldap_div::additional_fields($map_additional_fields,$user);
if (is_array($mapArray)) $insValues = t3lib_div::array_merge($insValues,
$mapArray);
$GLOBALS['TYPO3_DB']->exec_INSERTquery($user_table,$insValues);
}
}
} elseif ($username !='') {
tx_euldap_div::update_singleuser($Server, $arrGroups, $user, $user_table, $pid);
}
return ($return)?$content:$OK;
}
/**
* deletes typo user if not found in ldap
*
* @param array $arrServers: all ldap-server information (1-n)
* @param array $row: all user information
* @param string $user_table: fe_users or be_users
* @param [type] $delete: ...
* @return boolean true if successfully deleted
*/
function delete_user($arrServers, $row, $user_table, $delete=true) {
$i = 0;
$user_found = 0;
while ($i < sizeof($arrServers) && !$user_found) {
$ldapres = tx_euldap_div::search_ldap($arrServers[$i], $row['username']);
// HJM 2004-01-16: von == auf >= ge�ndert, da es im NML-Tree mehrere
Userobjecte gibt, die nicht anhand von
// Suchkriterien unterschieden werden k�nnen
$is_onlygroup = 0;
if ($ldapres['count'] >= 1) $user_found = 1;
$i++;
}
if (!$user_found) {
if ($delete) {
$dbres = $GLOBALS['TYPO3_DB']->exec_UPDATEquery(
$user_table,
'uid = '.$row['uid'].' AND deleted = 0',
Array(
'deleted' => '1'
)
);
} else {
$dbres = $GLOBALS['TYPO3_DB']->exec_UPDATEquery(
$user_table,
'uid = '.$row['uid'].' AND deleted = 0',
Array(
'disable' => '1'
)
);
}
return true;
} else {
return false;
}
}
/**
* checks username and password in ldap
*
* @param array $server_info: all ldap-server configuration needed (see table
eu_ldapserver)
* @param string $username: username to be checked in ldap
* @param string $password: password to be checked
* @return array ldap-user attributes, if found and authentificated
*/
function checkNTUser ($server_info, $username, $password) {
// convert character set local -> remote
$username = $this->csObj->conv($username, $this->localChar, $this->remoteChar);
$password = $this->csObj->conv($password, $this->localChar, $this->remoteChar);
$server = $server_info['server'];
$ldapport = $server_info['port'];
$domain = $server_info['domain'];
$base_dn = $server_info['base_dn'];
$cuser = $server_info['user'];
$cpass = $server_info['password'];
$servertype = $server_info['servertype'];
$version = $server_info['version'];
$strfilter = $server_info['filter'];
$filter = str_replace('<search>', $username, $strfilter);
if(!extension_loaded('ldap')) die('Your PHP version seems to lack LDAP support.
Please install.');
$ds = @ldap_connect($server, $ldapport);
if ($this->conf['logLevel'] == 2) t3lib_div::devLog('try to connect:
'.$server.':'.$ldapport, 'eu_ldap', 0);
if ($ds) {
if ($this->conf['logLevel'] == 2) t3lib_div::devLog('connect successful:
'.$server.':'.$ldapport, 'eu_ldap', -1);
if ($version == 3) ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3);
if ($this->conf['logLevel'] == 2) t3lib_div::devLog('server type: '.$servertype,
'eu_ldap', 0);
if ($servertype > 1) {
if ($this->conf['logLevel'] == 2) t3lib_div::devLog('try to bind: '.$cuser.' /
'.$cpass, 'eu_ldap', 0);
$r = @ldap_bind($ds, $cuser, $cpass);
if ($r) {
if ($this->conf['logLevel'] == 2) t3lib_div::devLog('bind successful',
'eu_ldap', -1);
$dn = @ldap_search($ds, $base_dn, $filter);
$dn = @ldap_get_entries($ds, $dn);
$username = $dn[0]['dn'];
} else {
if ($this->conf['logLevel'] == 2) t3lib_div::devLog('bind failed', 'eu_ldap',
2);
$username = null;
}
} elseif ($domain) {
if ($servertype == 0) {
$username = $domain."\\".$username;
} else {
$username = $username."@".$domain;
}
}
if ($username && $password) {
@ldap_set_option($ds, LDAP_OPT_REFERRALS, 0);
if ($this->conf['logLevel'] == 2) t3lib_div::devLog('try to bind: '.$username.'
/ '.$password, 'eu_ldap', 0);
$r = @ldap_bind($ds,$username,$password);
if ($r) {
if ($this->conf['logLevel'] == 2) t3lib_div::devLog('bind successful',
'eu_ldap', -1);
$dn = @ldap_search($ds, $base_dn, $filter);
$dn = @ldap_get_entries($ds, $dn);
$user = $dn[0];
// convert character set remote -> local
if (is_array($user)) $user = tx_euldap_div::convertArray($user,
$this->remoteChar, $this->localChar);
return $user;
} else {
if ($this->conf['logLevel'] == 2) t3lib_div::devLog('bind failed', 'eu_ldap',
2);
}
}
}
}
function convertArray($arr, $char1, $char2) {
while (list($k, $val) = each($arr)) {
if (is_array($val)) {
$arr[$k] = tx_euldap_div::convertArray($val, $char1, $char2);
} else {
$arr[$k] = $this->csObj->conv($val, $char1, $char2);
}
}
return $arr;
}
}
?>