|
eZ Publish
[4.0]
|
00001 <?php 00002 // 00003 // Definition of eZLDAPUser class 00004 // 00005 // Created on: <24-Jul-2003 15:48:06 wy> 00006 // 00007 // ## BEGIN COPYRIGHT, LICENSE AND WARRANTY NOTICE ## 00008 // SOFTWARE NAME: eZ Publish 00009 // SOFTWARE RELEASE: 4.0.x 00010 // COPYRIGHT NOTICE: Copyright (C) 1999-2008 eZ Systems AS 00011 // SOFTWARE LICENSE: GNU General Public License v2.0 00012 // NOTICE: > 00013 // This program is free software; you can redistribute it and/or 00014 // modify it under the terms of version 2.0 of the GNU General 00015 // Public License as published by the Free Software Foundation. 00016 // 00017 // This program is distributed in the hope that it will be useful, 00018 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00019 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00020 // GNU General Public License for more details. 00021 // 00022 // You should have received a copy of version 2.0 of the GNU General 00023 // Public License along with this program; if not, write to the Free 00024 // Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 00025 // MA 02110-1301, USA. 00026 // 00027 // 00028 // ## END COPYRIGHT, LICENSE AND WARRANTY NOTICE ## 00029 // 00030 00031 /*! \file ezldapuser.php 00032 */ 00033 00034 /*! 00035 \class eZLDAPUser ezldapuser.php 00036 \ingroup eZDatatype 00037 \brief The class eZLDAPUser does 00038 00039 */ 00040 //include_once( "kernel/classes/datatypes/ezuser/ezusersetting.php" ); 00041 //include_once( "kernel/classes/datatypes/ezuser/ezuser.php" ); 00042 //include_once( 'lib/ezutils/classes/ezini.php' ); 00043 00044 class eZLDAPUser extends eZUser 00045 { 00046 /*! 00047 Constructor 00048 */ 00049 function eZLDAPUser() 00050 { 00051 } 00052 00053 /*! 00054 \static 00055 Logs in the user if applied username and password is 00056 valid. The userID is returned if succesful, false if not. 00057 */ 00058 static function loginUser( $login, $password, $authenticationMatch = false ) 00059 { 00060 $http = eZHTTPTool::instance(); 00061 $db = eZDB::instance(); 00062 00063 if ( $authenticationMatch === false ) 00064 $authenticationMatch = eZUser::authenticationMatch(); 00065 00066 $loginEscaped = $db->escapeString( $login ); 00067 $passwordEscaped = $db->escapeString( $password ); 00068 00069 $loginArray = array(); 00070 if ( $authenticationMatch & eZUser::AUTHENTICATE_LOGIN ) 00071 $loginArray[] = "login='$loginEscaped'"; 00072 if ( $authenticationMatch & eZUser::AUTHENTICATE_EMAIL ) 00073 $loginArray[] = "email='$loginEscaped'"; 00074 if ( count( $loginArray ) == 0 ) 00075 $loginArray[] = "login='$loginEscaped'"; 00076 $loginText = implode( ' OR ', $loginArray ); 00077 00078 $contentObjectStatus = eZContentObject::STATUS_PUBLISHED; 00079 00080 $ini = eZINI::instance(); 00081 $LDAPIni = eZINI::instance( 'ldap.ini' ); 00082 $databaseName = $db->databaseName(); 00083 // if mysql 00084 if ( $databaseName === 'mysql' ) 00085 { 00086 $query = "SELECT contentobject_id, password_hash, password_hash_type, email, login 00087 FROM ezuser, ezcontentobject 00088 WHERE ( $loginText ) AND 00089 ezcontentobject.status='$contentObjectStatus' AND 00090 ( ezcontentobject.id=contentobject_id OR ( password_hash_type=4 AND ( $loginText ) AND password_hash=PASSWORD('$passwordEscaped') ) )"; 00091 } 00092 else 00093 { 00094 $query = "SELECT contentobject_id, password_hash, password_hash_type, email, login 00095 FROM ezuser, ezcontentobject 00096 WHERE ( $loginText ) AND 00097 ezcontentobject.status='$contentObjectStatus' AND 00098 ezcontentobject.id=contentobject_id"; 00099 } 00100 00101 $users = $db->arrayQuery( $query ); 00102 $exists = false; 00103 if ( count( $users ) >= 1 ) 00104 { 00105 foreach ( $users as $userRow ) 00106 { 00107 $userID = $userRow['contentobject_id']; 00108 $hashType = $userRow['password_hash_type']; 00109 $hash = $userRow['password_hash']; 00110 $exists = eZUser::authenticateHash( $userRow['login'], $password, eZUser::site(), 00111 $hashType, 00112 $hash ); 00113 00114 // If hash type is MySql 00115 if ( $hashType == eZUser::PASSWORD_HASH_MYSQL and $databaseName === 'mysql' ) 00116 { 00117 $queryMysqlUser = "SELECT contentobject_id, password_hash, password_hash_type, email, login 00118 FROM ezuser, ezcontentobject 00119 WHERE ezcontentobject.status='$contentObjectStatus' AND 00120 password_hash_type=4 AND ( $loginText ) AND password_hash=PASSWORD('$passwordEscaped') "; 00121 $mysqlUsers = $db->arrayQuery( $queryMysqlUser ); 00122 if ( count( $mysqlUsers ) >= 1 ) 00123 $exists = true; 00124 } 00125 00126 eZDebugSetting::writeDebug( 'kernel-user', eZUser::createHash( $userRow['login'], $password, eZUser::site(), 00127 $hashType ), "check hash" ); 00128 eZDebugSetting::writeDebug( 'kernel-user', $hash, "stored hash" ); 00129 // If current user has been disabled after a few failed login attempts. 00130 $canLogin = eZUser::isEnabledAfterFailedLogin( $userID ); 00131 00132 if ( $exists ) 00133 { 00134 // We should store userID for warning message. 00135 $GLOBALS['eZFailedLoginAttemptUserID'] = $userID; 00136 00137 $userSetting = eZUserSetting::fetch( $userID ); 00138 $isEnabled = $userSetting->attribute( "is_enabled" ); 00139 if ( $hashType != eZUser::hashType() and 00140 strtolower( $ini->variable( 'UserSettings', 'UpdateHash' ) ) == 'true' ) 00141 { 00142 $hashType = eZUser::hashType(); 00143 $hash = eZUser::createHash( $login, $password, eZUser::site(), 00144 $hashType ); 00145 $db->query( "UPDATE ezuser SET password_hash='$hash', password_hash_type='$hashType' WHERE contentobject_id='$userID'" ); 00146 } 00147 break; 00148 } 00149 } 00150 } 00151 if ( $exists and $isEnabled and $canLogin ) 00152 { 00153 eZDebugSetting::writeDebug( 'kernel-user', $userRow, 'user row' ); 00154 $user = new eZUser( $userRow ); 00155 eZDebugSetting::writeDebug( 'kernel-user', $user, 'user' ); 00156 $userID = $user->attribute( 'contentobject_id' ); 00157 00158 eZUser::updateLastVisit( $userID ); 00159 eZUser::setCurrentlyLoggedInUser( $user, $userID ); 00160 00161 // Reset number of failed login attempts 00162 eZUser::setFailedLoginAttempts( $userID, 0 ); 00163 00164 return $user; 00165 } 00166 else if ( $LDAPIni->variable( 'LDAPSettings', 'LDAPEnabled' ) == "true" ) 00167 { 00168 // read LDAP ini settings 00169 // and then try to bind to the ldap server 00170 00171 $LDAPVersion = $LDAPIni->variable( 'LDAPSettings', 'LDAPVersion' ); 00172 $LDAPServer = $LDAPIni->variable( 'LDAPSettings', 'LDAPServer' ); 00173 $LDAPPort = $LDAPIni->variable( 'LDAPSettings', 'LDAPPort' ); 00174 $LDAPBaseDN = $LDAPIni->variable( 'LDAPSettings', 'LDAPBaseDn' ); 00175 $LDAPBindUser = $LDAPIni->variable( 'LDAPSettings', 'LDAPBindUser' ); 00176 $LDAPBindPassword = $LDAPIni->variable( 'LDAPSettings', 'LDAPBindPassword' ); 00177 $LDAPSearchScope = $LDAPIni->variable( 'LDAPSettings', 'LDAPSearchScope' ); 00178 00179 $LDAPLoginAttribute = strtolower( $LDAPIni->variable( 'LDAPSettings', 'LDAPLoginAttribute' ) ); 00180 $LDAPFirstNameAttribute = strtolower( $LDAPIni->variable( 'LDAPSettings', 'LDAPFirstNameAttribute' ) ); 00181 $LDAPLastNameAttribute = strtolower( $LDAPIni->variable( 'LDAPSettings', 'LDAPLastNameAttribute' ) ); 00182 $LDAPEmailAttribute = strtolower( $LDAPIni->variable( 'LDAPSettings', 'LDAPEmailAttribute' ) ); 00183 00184 $defaultUserPlacement = $ini->variable( "UserSettings", "DefaultUserPlacement" ); 00185 00186 $LDAPUserGroupAttributeType = strtolower( $LDAPIni->variable( 'LDAPSettings', 'LDAPUserGroupAttributeType' ) ); 00187 $LDAPUserGroupAttribute = strtolower( $LDAPIni->variable( 'LDAPSettings', 'LDAPUserGroupAttribute' ) ); 00188 00189 if ( $LDAPIni->hasVariable( 'LDAPSettings', 'Utf8Encoding' ) ) 00190 { 00191 $Utf8Encoding = $LDAPIni->variable( 'LDAPSettings', 'Utf8Encoding' ); 00192 if ( $Utf8Encoding == "true" ) 00193 $isUtf8Encoding = true; 00194 else 00195 $isUtf8Encoding = false; 00196 } 00197 else 00198 { 00199 $isUtf8Encoding = false; 00200 } 00201 00202 if ( $LDAPIni->hasVariable( 'LDAPSettings', 'LDAPSearchFilters' ) ) 00203 { 00204 $LDAPFilters = $LDAPIni->variable( 'LDAPSettings', 'LDAPSearchFilters' ); 00205 } 00206 if ( $LDAPIni->hasVariable( 'LDAPSettings', 'LDAPUserGroupType' ) and $LDAPIni->hasVariable( 'LDAPSettings', 'LDAPUserGroup' ) ) 00207 { 00208 $LDAPUserGroupType = $LDAPIni->variable( 'LDAPSettings', 'LDAPUserGroupType' ); 00209 $LDAPUserGroup = $LDAPIni->variable( 'LDAPSettings', 'LDAPUserGroup' ); 00210 } 00211 00212 $LDAPFilter = "( &"; 00213 if ( count( $LDAPFilters ) > 0 ) 00214 { 00215 foreach ( array_keys( $LDAPFilters ) as $key ) 00216 { 00217 $LDAPFilter .= "(" . $LDAPFilters[$key] . ")"; 00218 } 00219 } 00220 $LDAPEqualSign = trim($LDAPIni->variable( 'LDAPSettings', "LDAPEqualSign" ) ); 00221 $LDAPBaseDN = str_replace( $LDAPEqualSign, "=", $LDAPBaseDN ); 00222 $LDAPFilter = str_replace( $LDAPEqualSign, "=", $LDAPFilter ); 00223 00224 $ds = ldap_connect( $LDAPServer, $LDAPPort ); 00225 00226 if ( $ds ) 00227 { 00228 ldap_set_option( $ds, LDAP_OPT_PROTOCOL_VERSION, $LDAPVersion ); 00229 if ( $LDAPBindUser == '' ) 00230 { 00231 $r = ldap_bind( $ds ); 00232 } 00233 else 00234 { 00235 $r = ldap_bind( $ds, $LDAPBindUser, $LDAPBindPassword ); 00236 } 00237 if ( !$r ) 00238 { 00239 // Increase number of failed login attempts. 00240 if ( isset( $userID ) ) 00241 eZUser::setFailedLoginAttempts( $userID ); 00242 00243 $user = false; 00244 return $user; 00245 } 00246 00247 $LDAPFilter .= "($LDAPLoginAttribute=$login)"; 00248 $LDAPFilter .= ")"; 00249 00250 ldap_set_option( $ds, LDAP_OPT_SIZELIMIT, 0 ); 00251 ldap_set_option( $ds, LDAP_OPT_TIMELIMIT, 0 ); 00252 00253 $retrieveAttributes = array( $LDAPLoginAttribute, 00254 $LDAPFirstNameAttribute, 00255 $LDAPLastNameAttribute, 00256 $LDAPEmailAttribute ); 00257 if ( $LDAPUserGroupAttributeType ) 00258 $retrieveAttributes[] = $LDAPUserGroupAttribute; 00259 00260 if ( $LDAPSearchScope == "one" ) 00261 $sr = ldap_list( $ds, $LDAPBaseDN, $LDAPFilter, $retrieveAttributes ); 00262 else if ( $LDAPSearchScope == "base" ) 00263 $sr = ldap_read( $ds, $LDAPBaseDN, $LDAPFilter, $retrieveAttributes ); 00264 else 00265 $sr = ldap_search( $ds, $LDAPBaseDN, $LDAPFilter, $retrieveAttributes ); 00266 00267 $info = ldap_get_entries( $ds, $sr ) ; 00268 if ( $info['count'] > 1 ) 00269 { 00270 // More than one user with same uid, not allow login. 00271 $user = false; 00272 return $user; 00273 } 00274 else if ( $info['count'] < 1 ) 00275 { 00276 // Increase number of failed login attempts. 00277 if ( isset( $userID ) ) 00278 eZUser::setFailedLoginAttempts( $userID ); 00279 00280 // user DN was not found 00281 $user = false; 00282 return $user; 00283 } 00284 00285 if( !$password ) 00286 { 00287 $password = crypt( microtime() ); 00288 } 00289 00290 // is it real authenticated LDAP user? 00291 if ( !@ldap_bind( $ds, $info[0]['dn'], $password ) ) 00292 { 00293 // Increase number of failed login attempts. 00294 if ( isset( $userID ) ) 00295 eZUser::setFailedLoginAttempts( $userID ); 00296 00297 $user = false; 00298 return $user; 00299 } 00300 00301 $extraNodeAssignments = array(); 00302 $userGroupClassID = $ini->variable( "UserSettings", "UserGroupClassID" ); 00303 00304 // default user group assigning 00305 if ( $LDAPUserGroupType != null ) 00306 { 00307 if ( $LDAPUserGroupType == "name" ) 00308 { 00309 if ( is_array( $LDAPUserGroup ) ) 00310 { 00311 foreach ( array_keys( $LDAPUserGroup ) as $key ) 00312 { 00313 $groupName = $LDAPUserGroup[$key]; 00314 $groupQuery = "SELECT ezcontentobject_tree.node_id 00315 FROM ezcontentobject, ezcontentobject_tree 00316 WHERE ezcontentobject.name like '$groupName' 00317 AND ezcontentobject.id=ezcontentobject_tree.contentobject_id 00318 AND ezcontentobject.contentclass_id=$userGroupClassID"; 00319 $groupObject = $db->arrayQuery( $groupQuery ); 00320 if ( count( $groupObject ) > 0 and $key == 0 ) 00321 { 00322 $defaultUserPlacement = $groupObject[0]['node_id']; 00323 } 00324 else if ( count( $groupObject ) > 0 ) 00325 { 00326 $extraNodeAssignments[] = $groupObject[0]['node_id']; 00327 } 00328 } 00329 } 00330 else 00331 { 00332 $groupName = $LDAPUserGroup; 00333 $groupQuery = "SELECT ezcontentobject_tree.node_id 00334 FROM ezcontentobject, ezcontentobject_tree 00335 WHERE ezcontentobject.name like '$groupName' 00336 AND ezcontentobject.id=ezcontentobject_tree.contentobject_id 00337 AND ezcontentobject.contentclass_id=$userGroupClassID"; 00338 $groupObject = $db->arrayQuery( $groupQuery ); 00339 00340 if ( count( $groupObject ) > 0 ) 00341 { 00342 $defaultUserPlacement = $groupObject[0]['node_id']; 00343 } 00344 } 00345 } 00346 else if ( $LDAPUserGroupType == "id" ) 00347 { 00348 if ( is_array( $LDAPUserGroup ) ) 00349 { 00350 foreach ( array_keys( $LDAPUserGroup ) as $key ) 00351 { 00352 $groupID = $LDAPUserGroup[$key]; 00353 $groupQuery = "SELECT ezcontentobject_tree.node_id 00354 FROM ezcontentobject, ezcontentobject_tree 00355 WHERE ezcontentobject.id='$groupID' 00356 AND ezcontentobject.id=ezcontentobject_tree.contentobject_id 00357 AND ezcontentobject.contentclass_id=$userGroupClassID"; 00358 $groupObject = $db->arrayQuery( $groupQuery ); 00359 if ( count( $groupObject ) > 0 and $key == 0 ) 00360 { 00361 $defaultUserPlacement = $groupObject[0]['node_id']; 00362 } 00363 else if ( count( $groupObject ) > 0 ) 00364 { 00365 $extraNodeAssignments[] = $groupObject[0]['node_id']; 00366 } 00367 } 00368 } 00369 else 00370 { 00371 $groupID = $LDAPUserGroup; 00372 $groupQuery = "SELECT ezcontentobject_tree.node_id 00373 FROM ezcontentobject, ezcontentobject_tree 00374 WHERE ezcontentobject.id='$groupID' 00375 AND ezcontentobject.id=ezcontentobject_tree.contentobject_id 00376 AND ezcontentobject.contentclass_id=$userGroupClassID"; 00377 $groupObject = $db->arrayQuery( $groupQuery ); 00378 00379 if ( count( $groupObject ) > 0 ) 00380 { 00381 $defaultUserPlacement = $groupObject[0]['node_id']; 00382 } 00383 } 00384 } 00385 } 00386 00387 $adminUser = eZUser::fetchByName( 'admin' ); 00388 $adminUserContentObjectID = $adminUser->attribute( 'contentobject_id' ); 00389 00390 // read group mapping LDAP settings 00391 $LDAPGroupMappingType = $LDAPIni->variable( 'LDAPSettings', 'LDAPGroupMappingType' ); 00392 $LDAPUserGroupMap = $LDAPIni->variable( 'LDAPSettings', 'LDAPUserGroupMap' ); 00393 00394 if ( !is_array( $LDAPUserGroupMap ) ) 00395 $LDAPUserGroupMap = array(); 00396 00397 // group mapping constants 00398 $ByMemberAttribute = 'SimpleMapping'; // by group's member attributes (with mapping) 00399 $ByMemberAttributeHierarhicaly = 'GetGroupsTree'; // by group's member attributes hierarhically 00400 $ByGroupAttribute = 'UseGroupAttribute'; // by user's group attribute (old style) 00401 $groupMappingTypes = array( $ByMemberAttribute, 00402 $ByMemberAttributeHierarhicaly, 00403 $ByGroupAttribute); 00404 00405 $userData =& $info[ 0 ]; 00406 00407 // default mapping using old style 00408 if ( !in_array( $LDAPGroupMappingType, $groupMappingTypes ) ) 00409 { 00410 $LDAPGroupMappingType = $ByGroupAttribute; 00411 } 00412 00413 if ( $LDAPGroupMappingType == $ByMemberAttribute or 00414 $LDAPGroupMappingType == $ByMemberAttributeHierarhicaly ) 00415 { 00416 $LDAPGroupBaseDN = $LDAPIni->variable( 'LDAPSettings', 'LDAPGroupBaseDN' ); 00417 $LDAPGroupClass = $LDAPIni->variable( 'LDAPSettings', 'LDAPGroupClass' ); 00418 00419 $LDAPGroupNameAttribute = strtolower( $LDAPIni->variable( 'LDAPSettings', 'LDAPGroupNameAttribute' ) ); 00420 $LDAPGroupMemberAttribute = strtolower( $LDAPIni->variable( 'LDAPSettings', 'LDAPGroupMemberAttribute' ) ); 00421 $LDAPGroupDescriptionAttribute = strtolower( $LDAPIni->variable( 'LDAPSettings', 'LDAPGroupDescriptionAttribute' ) ); 00422 00423 $groupSearchingDepth = ( $LDAPGroupMappingType == '1' ) ? 1 : 1000; 00424 00425 // now, get all parents for currently ldap authenticated user 00426 $requiredParams = array(); 00427 $requiredParams[ 'LDAPLoginAttribute' ] = $LDAPLoginAttribute; 00428 $requiredParams[ 'LDAPGroupBaseDN' ] = $LDAPGroupBaseDN; 00429 $requiredParams[ 'LDAPGroupClass' ] = $LDAPGroupClass; 00430 $requiredParams[ 'LDAPGroupNameAttribute' ] = $LDAPGroupNameAttribute; 00431 $requiredParams[ 'LDAPGroupMemberAttribute' ] = $LDAPGroupMemberAttribute; 00432 $requiredParams[ 'LDAPGroupDescriptionAttribute' ] = $LDAPGroupDescriptionAttribute; 00433 $requiredParams[ 'ds' ] =& $ds; 00434 $requiredParams[ 'TopUserGroupNodeID' ] = 5; 00435 00436 $groupsTree = array(); 00437 $stack = array(); 00438 $newfilter = '(&(objectClass=' . $LDAPGroupClass . ')(' . $LDAPGroupMemberAttribute . '=' . $userData['dn'] . '))'; 00439 00440 $groupsTree[ $userData['dn'] ] = array( 'data' => & $userData, 00441 'parents' => array(), 00442 'children' => array() ); 00443 00444 eZLDAPUser::getUserGroupsTree( $requiredParams, $newfilter, $userData['dn'], $groupsTree, $stack, $groupSearchingDepth ); 00445 $userRecord =& $groupsTree[ $userData['dn'] ]; 00446 00447 if ( $LDAPGroupMappingType == $ByMemberAttribute ) 00448 { 00449 if ( count( $userRecord[ 'parents' ] ) > 0 ) 00450 { 00451 $remappedGroupNames = array(); 00452 foreach ( array_keys( $userRecord[ 'parents' ] ) as $key ) 00453 { 00454 $parentGroup =& $userRecord[ 'parents' ][ $key ]; 00455 if ( isset( $parentGroup[ 'data' ][ $LDAPGroupNameAttribute ] ) ) 00456 { 00457 $ldapGroupName = $parentGroup[ 'data' ][ $LDAPGroupNameAttribute ]; 00458 if ( is_array( $ldapGroupName ) ) 00459 { 00460 $ldapGroupName = ( $ldapGroupName[ 'count' ] > 0 ) ? $ldapGroupName[ 0 ] : ''; 00461 } 00462 00463 // remap group name and check that group exists 00464 if ( array_key_exists( $ldapGroupName, $LDAPUserGroupMap ) ) 00465 { 00466 $remmapedGroupName = $LDAPUserGroupMap[ $ldapGroupName ]; 00467 $groupQuery = "SELECT ezcontentobject_tree.node_id 00468 FROM ezcontentobject, ezcontentobject_tree 00469 WHERE ezcontentobject.name like '$remmapedGroupName' 00470 AND ezcontentobject.id=ezcontentobject_tree.contentobject_id 00471 AND ezcontentobject.contentclass_id=$userGroupClassID"; 00472 $groupRow = $db->arrayQuery( $groupQuery ); 00473 00474 if ( count( $groupRow ) > 0 ) 00475 { 00476 $userRecord['new_parents'][] = $groupRow[ 0 ][ 'node_id' ]; 00477 } 00478 } 00479 } 00480 } 00481 } 00482 } 00483 else if ( $LDAPGroupMappingType == $ByMemberAttributeHierarhicaly ) 00484 { 00485 eZUser::setCurrentlyLoggedInUser( $adminUser, $adminUserContentObjectID ); 00486 00487 $stack = array(); 00488 self::goAndPublishGroups( $requiredParams, $userData['dn'], $groupsTree, $stack, $groupSearchingDepth, true ); 00489 } 00490 if ( isset( $userRecord['new_parents'] ) and 00491 count( $userRecord['new_parents'] ) > 0 ) 00492 { 00493 $defaultUserPlacement = $userRecord['new_parents'][0]; 00494 $extraNodeAssignments = array_merge( $extraNodeAssignments, $userRecord['new_parents'] ); 00495 } 00496 } 00497 else if ( $LDAPGroupMappingType == $ByGroupAttribute ) // old style mapping by group (employeetype) attribute 00498 { 00499 if ( $LDAPUserGroupAttributeType ) 00500 { 00501 $groupAttributeCount = $info[0][$LDAPUserGroupAttribute]['count']; 00502 if ( $LDAPUserGroupAttributeType == "name" ) 00503 { 00504 for ( $i = 0; $i < $groupAttributeCount; $i++ ) 00505 { 00506 if ( $isUtf8Encoding ) 00507 { 00508 $groupName = utf8_decode( $info[0][$LDAPUserGroupAttribute][$i] ); 00509 } 00510 else 00511 { 00512 $groupName = $info[0][$LDAPUserGroupAttribute][$i]; 00513 } 00514 if ( $groupName != null ) 00515 { 00516 $groupQuery = "SELECT ezcontentobject_tree.node_id 00517 FROM ezcontentobject, ezcontentobject_tree 00518 WHERE ezcontentobject.name like '$groupName' 00519 AND ezcontentobject.id=ezcontentobject_tree.contentobject_id 00520 AND ezcontentobject.contentclass_id=$userGroupClassID"; 00521 $groupObject = $db->arrayQuery( $groupQuery ); 00522 00523 if ( count( $groupObject ) > 0 and $i == 0 ) 00524 { 00525 $defaultUserPlacement = $groupObject[0]['node_id']; 00526 } 00527 else if ( count( $groupObject ) > 0 ) 00528 { 00529 $extraNodeAssignments[] = $groupObject[0]['node_id']; 00530 } 00531 } 00532 } 00533 } 00534 else if ( $LDAPUserGroupAttributeType == "id" ) 00535 { 00536 for ( $i = 0; $i < $groupAttributeCount; $i++ ) 00537 { 00538 if ( $isUtf8Encoding ) 00539 { 00540 $groupID = utf8_decode( $info[0][$LDAPUserGroupAttribute][$i] ); 00541 } 00542 else 00543 { 00544 $groupID = $info[0][$LDAPUserGroupAttribute][$i]; 00545 } 00546 00547 if ( $groupID != null ) 00548 { 00549 $groupName = "LDAP " . $groupID; 00550 $groupQuery = "SELECT ezcontentobject_tree.node_id 00551 FROM ezcontentobject, ezcontentobject_tree 00552 WHERE ezcontentobject.name like '$groupName' 00553 AND ezcontentobject.id=ezcontentobject_tree.contentobject_id 00554 AND ezcontentobject.contentclass_id=$userGroupClassID"; 00555 $groupObject = $db->arrayQuery( $groupQuery ); 00556 00557 if ( count( $groupObject ) > 0 and $i == 0 ) 00558 { 00559 $defaultUserPlacement = $groupObject[0]['node_id']; 00560 } 00561 else if ( count( $groupObject ) > 0 ) 00562 { 00563 $extraNodeAssignments[] = $groupObject[0]['node_id']; 00564 } 00565 } 00566 } 00567 } 00568 } 00569 } 00570 00571 $userAttributes = array( 'login' => $login, 00572 'first_name' => isset( $userData[ $LDAPFirstNameAttribute ] ) ? $userData[ $LDAPFirstNameAttribute ][0] : false, 00573 'last_name' => isset( $userData[ $LDAPLastNameAttribute ] ) ? $userData[ $LDAPLastNameAttribute ][0] : false, 00574 'email' => isset( $userData[ $LDAPEmailAttribute ] ) ? $userData[ $LDAPEmailAttribute ][0] : false ); 00575 00576 $oldUser = clone eZUser::currentUser(); 00577 eZUser::setCurrentlyLoggedInUser( $adminUser, $adminUserContentObjectID ); 00578 $existingUser = eZLDAPUser::publishUpdateUser( $extraNodeAssignments, $defaultUserPlacement, $userAttributes, $isUtf8Encoding ); 00579 00580 if ( is_object( $existingUser ) ) 00581 { 00582 eZUser::setCurrentlyLoggedInUser( $existingUser, $existingUser->attribute( 'contentobject_id' ) ); 00583 } 00584 else 00585 { 00586 eZUser::setCurrentlyLoggedInUser( $oldUser, $oldUser->attribute( 'contentobject_id' ) ); 00587 } 00588 00589 ldap_close( $ds ); 00590 return $existingUser; 00591 } 00592 else 00593 { 00594 eZDebug::writeError( 'Cannot initialize connection for LDAP server', 'eZLDAPUser::loginUser()' ); 00595 $user = false; 00596 return $user; 00597 } 00598 } 00599 else 00600 { 00601 // Increase number of failed login attempts. 00602 if ( isset( $userID ) ) 00603 eZUser::setFailedLoginAttempts( $userID ); 00604 00605 $user = false; 00606 return $user; 00607 } 00608 } 00609 00610 /* 00611 Static method, for internal usage only. 00612 Publishes new or update existing user 00613 */ 00614 static function publishUpdateUser( $parentNodeIDs, $defaultUserPlacement, $userAttributes, $isUtf8Encoding = false ) 00615 { 00616 $thisFunctionErrorLabel = 'eZLDAPUser.php, function publishUpdateUser()'; 00617 00618 if ( !is_array( $userAttributes ) or 00619 !isset( $userAttributes[ 'login' ] ) or empty( $userAttributes[ 'login' ] ) ) 00620 { 00621 eZDebug::writeWarning( 'Empty user login passed.', 00622 $thisFunctionErrorLabel ); 00623 return false; 00624 } 00625 00626 if ( ( !is_array( $parentNodeIDs ) or count( $parentNodeIDs ) < 1 ) and 00627 !is_numeric( $defaultUserPlacement ) ) 00628 { 00629 eZDebug::writeWarning( 'No one parent node IDs was passed for publishing new user (login = "' . 00630 $userAttributes[ 'login' ] . '")', 00631 $thisFunctionErrorLabel ); 00632 return false; 00633 } 00634 $parentNodeIDs[] = $defaultUserPlacement; 00635 $parentNodeIDs = array_unique( $parentNodeIDs ); 00636 00637 00638 $login = $userAttributes[ 'login' ]; 00639 $first_name = $userAttributes[ 'first_name' ]; 00640 $last_name = $userAttributes[ 'last_name' ]; 00641 $email = $userAttributes[ 'email' ]; 00642 00643 if ( $isUtf8Encoding ) 00644 { 00645 $first_name = utf8_decode( $first_name ); 00646 $last_name = utf8_decode( $last_name ); 00647 } 00648 00649 $user = eZUser::fetchByName( $login ); 00650 $createNewUser = ( is_object( $user ) ) ? false : true; 00651 00652 if ( $createNewUser ) 00653 { 00654 if ( !isset( $first_name ) or empty( $first_name ) or 00655 !isset( $last_name ) or empty( $last_name ) or 00656 !isset( $email ) or empty( $email ) ) 00657 { 00658 eZDebug::writeWarning( 'Cannot create user with empty first name (last name or email).', 00659 $thisFunctionErrorLabel ); 00660 return false; 00661 } 00662 00663 $ini = eZINI::instance(); 00664 $userClassID = $ini->variable( "UserSettings", "UserClassID" ); 00665 $userCreatorID = $ini->variable( "UserSettings", "UserCreatorID" ); 00666 $defaultSectionID = $ini->variable( "UserSettings", "DefaultSectionID" ); 00667 00668 $class = eZContentClass::fetch( $userClassID ); 00669 $contentObject = $class->instantiate( $userCreatorID, $defaultSectionID ); 00670 00671 $contentObject->store(); 00672 00673 $userID = $contentObjectID = $contentObject->attribute( 'id' ); 00674 00675 $version = $contentObject->version( 1 ); 00676 $version->setAttribute( 'modified', time() ); 00677 $version->setAttribute( 'status', eZContentObjectVersion::STATUS_DRAFT ); 00678 $version->store(); 00679 00680 $user = eZLDAPUser::create( $userID ); 00681 $user->setAttribute( 'login', $login ); 00682 } 00683 else 00684 { 00685 $userID = $contentObjectID = $user->attribute( 'contentobject_id' ); 00686 $contentObject = eZContentObject::fetch( $userID ); 00687 $version = $contentObject->attribute( 'current' ); 00688 } 00689 00690 //================= common part 1: start ======================== 00691 $contentObjectAttributes = $version->contentObjectAttributes(); 00692 00693 // find and set 'name' and 'description' attributes (as standard user group class) 00694 $firstNameIdentifier = 'first_name'; 00695 $lastNameIdentifier = 'last_name'; 00696 $firstNameAttribute = null; 00697 $lastNameAttribute = null; 00698 00699 foreach ( $contentObjectAttributes as $attribute ) 00700 { 00701 if ( $attribute->attribute( 'contentclass_attribute_identifier' ) == $firstNameIdentifier ) 00702 { 00703 $firstNameAttribute = $attribute; 00704 } 00705 else if ( $attribute->attribute( 'contentclass_attribute_identifier' ) == $lastNameIdentifier ) 00706 { 00707 $lastNameAttribute = $attribute; 00708 } 00709 } 00710 //================= common part 1: end ========================== 00711 00712 // If we are updating an existing user, we must find out if some data should be changed. 00713 // In that case, we must create a new version and publish it. 00714 if ( !$createNewUser ) 00715 { 00716 $userDataChanged = false; 00717 $firstNameChanged = false; 00718 $lastNameChanged = false; 00719 $emailChanged = false; 00720 00721 if ( $firstNameAttribute and $firstNameAttribute->attribute( 'data_text' ) != $first_name ) 00722 { 00723 $firstNameChanged = true; 00724 } 00725 $firstNameAttribute = false; // We will load this again from the new version we will create, if it has changed 00726 if ( $lastNameAttribute and $lastNameAttribute->attribute( 'data_text' ) != $last_name ) 00727 { 00728 $lastNameChanged = true; 00729 } 00730 $lastNameAttribute = false; // We will load this again from the new version we will create, if it has changed 00731 if ( $user->attribute( 'email' ) != $email ) 00732 { 00733 $emailChanged = true; 00734 } 00735 00736 if ( $firstNameChanged or $lastNameChanged or $emailChanged ) 00737 { 00738 $userDataChanged = true; 00739 // Create new version 00740 $version = $contentObject->createNewVersion(); 00741 $contentObjectAttributes = $version->contentObjectAttributes(); 00742 foreach ( $contentObjectAttributes as $attribute ) 00743 { 00744 if ( $attribute->attribute( 'contentclass_attribute_identifier' ) == $firstNameIdentifier ) 00745 { 00746 $firstNameAttribute = $attribute; 00747 } 00748 else if ( $attribute->attribute( 'contentclass_attribute_identifier' ) == $lastNameIdentifier ) 00749 { 00750 $lastNameAttribute = $attribute; 00751 } 00752 } 00753 } 00754 } 00755 00756 //================= common part 2: start ======================== 00757 if ( $firstNameAttribute ) 00758 { 00759 $firstNameAttribute->setAttribute( 'data_text', $first_name ); 00760 $firstNameAttribute->store(); 00761 } 00762 if ( $lastNameAttribute ) 00763 { 00764 $lastNameAttribute->setAttribute( 'data_text', $last_name ); 00765 $lastNameAttribute->store(); 00766 } 00767 00768 if ( !isset( $userDataChanged ) or $userDataChanged === true ) 00769 { 00770 $contentClass = $contentObject->attribute( 'content_class' ); 00771 $name = $contentClass->contentObjectName( $contentObject ); 00772 $contentObject->setName( $name ); 00773 } 00774 00775 if ( !isset( $emailChanged ) or $emailChanged === true ) 00776 { 00777 $user->setAttribute( 'email', $email ); 00778 } 00779 00780 $user->setAttribute( 'password_hash', "" ); 00781 $user->setAttribute( 'password_hash_type', 0 ); 00782 $user->store(); 00783 00784 $debugArray = array( 'Updating user data', 00785 'createNewUser' => $createNewUser, 00786 'userDataChanged' => isset( $userDataChanged ) ? $userDataChanged : null, 00787 'login' => $login, 00788 'first_name' => $first_name, 00789 'last_name' => $last_name, 00790 'email' => $email, 00791 'firstNameAttribute is_object' => is_object( $firstNameAttribute ), 00792 'lastNameAttribute is_object' => is_object( $lastNameAttribute ), 00793 'content object id' => $contentObjectID, 00794 'version id' => $version->attribute( 'version' ) 00795 ); 00796 eZDebug::writeNotice( var_export( $debugArray, true ), __METHOD__ ); 00797 //================= common part 2: end ========================== 00798 00799 if ( $createNewUser ) 00800 { 00801 reset( $parentNodeIDs ); 00802 // prepare node assignments for publishing new user 00803 foreach( $parentNodeIDs as $parentNodeID ) 00804 { 00805 $newNodeAssignment = eZNodeAssignment::create( array( 'contentobject_id' => $contentObjectID, 00806 'contentobject_version' => 1, 00807 'parent_node' => $parentNodeID, 00808 'is_main' => ( $defaultUserPlacement == $parentNodeID ? 1 : 0 ) ) ); 00809 $newNodeAssignment->setAttribute( 'parent_remote_id', uniqid( 'LDAP_' ) ); 00810 $newNodeAssignment->store(); 00811 } 00812 00813 //include_once( 'lib/ezutils/classes/ezoperationhandler.php' ); 00814 $operationResult = eZOperationHandler::execute( 'content', 'publish', array( 'object_id' => $contentObjectID, 00815 'version' => 1 ) ); 00816 } 00817 else 00818 { 00819 if ( $userDataChanged ) 00820 { 00821 // Publish object 00822 $operationResult = eZOperationHandler::execute( 'content', 'publish', array( 'object_id' => $contentObjectID, 00823 'version' => $version->attribute( 'version' ) ) ); 00824 } 00825 00826 $LDAPIni = eZINI::instance( 'ldap.ini' ); 00827 $keepGroupAssignment = ( $LDAPIni->hasVariable( 'LDAPSettings', 'KeepGroupAssignment' ) ) ? 00828 ( $LDAPIni->variable( 'LDAPSettings', 'KeepGroupAssignment' ) == "enabled" ) : false; 00829 00830 if ( $keepGroupAssignment == false ) 00831 { 00832 $objectIsChanged = false; 00833 00834 $db = eZDB::instance(); 00835 $db->begin(); 00836 00837 // First check existing assignments, remove any that should not exist 00838 $assignedNodesList = $contentObject->assignedNodes(); 00839 $existingParentNodeIDs = array(); 00840 foreach ( $assignedNodesList as $node ) 00841 { 00842 $parentNodeID = $node->attribute( 'parent_node_id' ); 00843 if ( !in_array( $parentNodeID, $parentNodeIDs ) ) 00844 { 00845 $node->removeThis(); 00846 $objectIsChanged = true; 00847 } 00848 else 00849 { 00850 $existingParentNodeIDs[] = $parentNodeID; 00851 } 00852 } 00853 00854 // Then check assignments that should exist, add them if they are missing 00855 foreach( $parentNodeIDs as $parentNodeID ) 00856 { 00857 if ( !in_array( $parentNodeID, $existingParentNodeIDs ) ) 00858 { 00859 $newNode = $contentObject->addLocation( $parentNodeID, true ); 00860 $newNode->updateSubTreePath(); 00861 $newNode->setAttribute( 'contentobject_is_published', 1 ); 00862 $newNode->sync(); 00863 $existingParentNodeIDs[] = $parentNodeID; 00864 $objectIsChanged = true; 00865 } 00866 } 00867 00868 // Then ensure that the main node is correct 00869 $currentMainParentNodeID = $contentObject->attribute( 'main_parent_node_id' ); 00870 if ( $currentMainParentNodeID != $defaultUserPlacement ) 00871 { 00872 $existingNode = eZContentObjectTreeNode::fetchNode( $contentObjectID, $defaultUserPlacement ); 00873 if ( !is_object( $existingNode ) ) 00874 { 00875 eZDebug::writeError( "Cannot find assigned node as $defaultUserPlacement's child.", __METHOD__ ); 00876 } 00877 else 00878 { 00879 $existingNodeID = $existingNode->attribute( 'node_id' ); 00880 $versionNum = $version->attribute( 'version' ); 00881 eZContentObjectTreeNode::updateMainNodeID( $existingNodeID, $contentObjectID, $versionNum, $defaultUserPlacement ); 00882 $objectIsChanged = true; 00883 } 00884 } 00885 00886 $db->commit(); 00887 00888 // Finally, clear object view cache if something was changed 00889 if ( $objectIsChanged ) 00890 { 00891 eZContentCacheManager::clearObjectViewCache( $contentObjectID, true ); 00892 } 00893 } 00894 } 00895 00896 eZUser::updateLastVisit( $userID ); 00897 //eZUser::setCurrentlyLoggedInUser( $user, $userID ); 00898 // Reset number of failed login attempts 00899 eZUser::setFailedLoginAttempts( $userID, 0 ); 00900 return $user; 00901 } 00902 00903 /* 00904 Static method, for internal usage only. 00905 Note: used user group class (see 'UserGroupClassID' ini setting, in 'UserSettings' section) 00906 must have name attribute with indentifier equal 'name' 00907 */ 00908 static function publishNewUserGroup( $parentNodeIDs, $newGroupAttributes, $isUtf8Encoding = false ) 00909 { 00910 $thisFunctionErrorLabel = 'eZLDAPUser.php, function publishNewUserGroup()'; 00911 $newNodeIDs = array(); 00912 00913 if ( !is_array( $newGroupAttributes ) or 00914 !isset( $newGroupAttributes[ 'name' ] ) or 00915 empty( $newGroupAttributes[ 'name' ] ) ) 00916 { 00917 eZDebug::writeWarning( 'Cannot create user group with empty name.', 00918 $thisFunctionErrorLabel ); 00919 return $newNodeIDs; 00920 } 00921 if ( !is_array( $parentNodeIDs ) or count( $parentNodeIDs ) < 1 ) 00922 { 00923 eZDebug::writeWarning( 'No one parent node IDs was passed for publishing new group (group name = "' . 00924 $newGroupAttributes[ 'name' ] . '")', 00925 $thisFunctionErrorLabel ); 00926 return $newNodeIDs; 00927 } 00928 00929 $ini = eZINI::instance(); 00930 $userGroupClassID = $ini->variable( "UserSettings", "UserGroupClassID" ); 00931 $userCreatorID = $ini->variable( "UserSettings", "UserCreatorID" ); 00932 $defaultSectionID = $ini->variable( "UserSettings", "DefaultSectionID" ); 00933 00934 $userGroupClass = eZContentClass::fetch( $userGroupClassID ); 00935 $contentObject = $userGroupClass->instantiate( $userCreatorID, $defaultSectionID ); 00936 00937 $contentObject->store(); 00938 00939 $contentObjectID = $contentObject->attribute( 'id' ); 00940 00941 reset( $parentNodeIDs ); 00942 $defaultPlacement = current( $parentNodeIDs ); 00943 array_shift( $parentNodeIDs ); 00944 00945 $nodeAssignment = eZNodeAssignment::create( array( 'contentobject_id' => $contentObjectID, 00946 'contentobject_version' => 1, 00947 'parent_node' => $defaultPlacement, 00948 'is_main' => 1 ) ); 00949 $nodeAssignment->setAttribute( 'parent_remote_id', uniqid( 'LDAP_' ) ); 00950 $nodeAssignment->store(); 00951 00952 foreach( $parentNodeIDs as $parentNodeID ) 00953 { 00954 $newNodeAssignment = eZNodeAssignment::create( array( 'contentobject_id' => $contentObjectID, 00955 'contentobject_version' => 1, 00956 'parent_node' => $parentNodeID, 00957 'is_main' => 0 ) ); 00958 $newNodeAssignment->setAttribute( 'parent_remote_id', uniqid( 'LDAP_' ) ); 00959 $newNodeAssignment->store(); 00960 } 00961 00962 $version = $contentObject->version( 1 ); 00963 $version->setAttribute( 'modified', time() ); 00964 $version->setAttribute( 'status', eZContentObjectVersion::STATUS_DRAFT ); 00965 $version->store(); 00966 00967 $contentObjectAttributes = $version->contentObjectAttributes(); 00968 00969 // find ant set 'name' and 'description' attributes (as standard user group class) 00970 $nameIdentifier = 'name'; 00971 $descIdentifier = 'description'; 00972 $nameContentAttribute = null; 00973 $descContentAttribute = null; 00974 foreach( $contentObjectAttributes as $attribute ) 00975 { 00976 if ( $attribute->attribute( 'contentclass_attribute_identifier' ) == $nameIdentifier ) 00977 { 00978 $nameContentAttribute = $attribute; 00979 } 00980 else if ( $attribute->attribute( 'contentclass_attribute_identifier' ) == $descIdentifier ) 00981 { 00982 $descContentAttribute = $attribute; 00983 } 00984 } 00985 if ( $nameContentAttribute ) 00986 { 00987 if ( $isUtf8Encoding ) 00988 $newGroupAttributes[ 'name' ] = utf8_decode( $newGroupAttributes[ 'name' ] ); 00989 $nameContentAttribute->setAttribute( 'data_text', $newGroupAttributes[ 'name' ] ); 00990 $nameContentAttribute->store(); 00991 } 00992 if ( $descContentAttribute and 00993 isset( $newGroupAttributes[ 'description' ] ) ) 00994 { 00995 if ( $isUtf8Encoding ) 00996 $newGroupAttributes[ 'description' ] = utf8_decode( $newGroupAttributes[ 'description' ] ); 00997 $descContentAttribute->setAttribute( 'data_text', $newGroupAttributes[ 'description' ] ); 00998 $descContentAttribute->store(); 00999 } 01000 01001 //include_once( 'lib/ezutils/classes/ezoperationhandler.php' ); 01002 $operationResult = eZOperationHandler::execute( 'content', 'publish', array( 'object_id' => $contentObjectID, 01003 'version' => 1 ) ); 01004 $newNodes = eZContentObjectTreeNode::fetchByContentObjectID( $contentObjectID, true, 1 ); 01005 foreach ( $newNodes as $newNode ) 01006 { 01007 $newNodeIDs[] = $newNode->attribute( 'node_id' ); 01008 } 01009 01010 return $newNodeIDs; 01011 } 01012 01013 /* 01014 Static method, for internal usage only. 01015 Recursive, publishes groups by prepared tree of groups returned by getUserGroupsTree() method 01016 */ 01017 static function goAndPublishGroups( &$requiredParams, 01018 $curDN, 01019 &$groupsTree, 01020 &$stack, 01021 $depth, 01022 $isUser = false ) 01023 { 01024 $thisFunctionErrorLabel = 'eZLDAPUser.php, function goAndPublishGroups()'; 01025 if ( !isset( $groupsTree[ $curDN ] ) ) 01026 { 01027 eZDebug::writeError( 'Passed $curDN is not in result tree array.', 01028 $thisFunctionErrorLabel ); 01029 return false; 01030 } 01031 01032 array_push( $stack, $curDN ); 01033 $current =& $groupsTree[ $curDN ]; 01034 01035 // check the name 01036 if ( $isUser ) 01037 { 01038 $currentName = $current[ 'data' ][ $requiredParams[ 'LDAPLoginAttribute' ] ]; 01039 } 01040 else 01041 { 01042 $currentName = $current[ 'data' ][ $requiredParams[ 'LDAPGroupNameAttribute' ] ]; 01043 } 01044 01045 if ( is_array( $currentName ) and //count( $currentName ) > 1 and 01046 isset( $currentName[ 'count' ] ) and $currentName[ 'count' ] > 0 ) 01047 { 01048 $currentName = $currentName[ 0 ]; 01049 } 01050 01051 if ( empty( $currentName ) ) 01052 { 01053 eZDebug::writeWarning( "Cannot create/use group with empty name (dn = $curDN)", 01054 $thisFunctionErrorLabel ); 01055 return false; 01056 } 01057 01058 // go through parents 01059 if ( is_array( $current['parents'] ) and count( $current['parents'] ) > 0 ) 01060 { 01061 foreach( array_keys( $current['parents'] ) as $key ) 01062 { 01063 $parent =& $groupsTree[ $key ]; 01064 01065 if ( in_array( $parent['data']['dn'], $stack ) ) 01066 { 01067 $groupsTree[ '_recursion_detected_' ] = true; 01068 eZDebug::writeError( 'Recursion is detected in the user-groups tree while getting parent groups for ' . $curDN, 01069 $thisFunctionErrorLabel ); 01070 return false; 01071 } 01072 if ( isset( $parent[ 'nodes' ] ) and count( $parent[ 'nodes' ] ) > 0 ) 01073 { 01074 continue; 01075 } 01076 $ret = self::goAndPublishGroups( $requiredParams, 01077 $parent['data']['dn'], 01078 $groupsTree, 01079 $stack, 01080 $depth - 1 ); 01081 if ( isset( $groupsTree[ '_recursion_detected_' ] ) and $groupsTree[ '_recursion_detected_' ] ) 01082 { 01083 return false; 01084 } 01085 } 01086 } 01087 else 01088 { 01089 // We've reached a top node 01090 if ( !isset( $groupsTree[ 'root' ] ) ) 01091 { 01092 $groupsTree[ 'root' ] = array( 'data' => null, 01093 'parents' => null, 01094 'children' => array(), 01095 'nodes' => array( $requiredParams[ 'TopUserGroupNodeID' ] ) ); 01096 } 01097 if ( !isset( $groupsTree[ 'root' ][ 'children' ][ $curDN ] ) ) 01098 $groupsTree[ 'root' ][ 'children' ][ $curDN ] =& $current; 01099 if ( !isset( $current[ 'parents' ][ 'root' ] ) ) 01100 $current[ 'parents' ][ 'root' ] =& $groupsTree[ 'root' ]; 01101 } 01102 01103 if ( !isset( $current[ 'nodes' ] ) ) 01104 $current[ 'nodes' ] = array(); 01105 01106 $parentNodesForNew = array(); 01107 foreach( array_keys( $current[ 'parents' ] ) as $key ) 01108 { 01109 $parent =& $groupsTree[ $key ]; 01110 if ( is_array( $parent[ 'nodes' ] ) and count( $parent[ 'nodes' ] ) > 0 ) 01111 { 01112 foreach ( $parent[ 'nodes' ] as $parentNodeID ) 01113 { 01114 // fetch current parent node 01115 $parentNode = eZContentObjectTreeNode::fetch( $parentNodeID ); 01116 if ( is_object( $parentNode ) ) 01117 { 01118 $params = array( 'Depth' => 1, 01119 'AttributeFilter' => array( array( 'name', '=', $currentName ) ) ); 01120 $nodes = eZContentObjectTreeNode::subTreeByNodeID( $params, $parentNodeID ); 01121 01122 if ( is_array( $nodes ) and count( $nodes ) > 0 and !$isUser ) 01123 { 01124 // if group with given name already exist under $parentNode then get fetch 01125 // group node and remember its ID 01126 $node =& $nodes[ 0 ]; 01127 $nodeID = $node->attribute( 'node_id' ); 01128 $current[ 'nodes' ][] = $nodeID; 01129 } 01130 else 01131 { 01132 // if not exist then remember $parentNodeID to publish a new one 01133 $parentNodesForNew[] = $parentNodeID; 01134 } 01135 } 01136 else 01137 { 01138 eZDebug::writeError( 'Cannot fetch parent node for creating new user group ' . $parentNodeID, 01139 $thisFunctionErrorLabel ); 01140 } 01141 } 01142 } 01143 else 01144 { 01145 eZDebug::writeError( "Cannot get any published parent group for group/user with name = '$currentName'" . 01146 " (dn = '" . $current[ 'data' ]['dn'] . "')", 01147 $thisFunctionErrorLabel ); 01148 } 01149 } 01150 01151 if ( count( $parentNodesForNew ) > 0 ) 01152 { 01153 if ( $isUser ) 01154 { 01155 $current[ 'new_parents' ] = $parentNodesForNew; 01156 $newNodeIDs = array(); 01157 } 01158 else 01159 { 01160 $newNodeIDs = eZLDAPUser::publishNewUserGroup( $parentNodesForNew, array( 'name' => $currentName, 01161 'description' => '' ) ); 01162 } 01163 $current[ 'nodes' ] = array_merge( $current[ 'nodes' ], $newNodeIDs ); 01164 } 01165 01166 array_pop( $stack ); 01167 return true; 01168 } 01169 01170 /* 01171 Static method, for internal usage only 01172 Recursive method, which parses tree of groups from ldap server 01173 */ 01174 static function getUserGroupsTree( &$requiredParams, 01175 $filter, 01176 $curDN, 01177 &$groupsTree, 01178 &$stack, // stack for recursion checking 01179 $depth = 0 ) 01180 { 01181 if ( $depth == 0 ) 01182 { 01183 return false; 01184 } 01185 $thisFunctionErrorLabel = 'eZLDAPUser.php, function getUserGroupsTree()'; 01186 01187 if ( !isset( $requiredParams[ 'LDAPGroupBaseDN' ] ) or empty( $requiredParams[ 'LDAPGroupBaseDN' ] ) or 01188 !isset( $requiredParams[ 'LDAPGroupClass' ] ) or empty( $requiredParams[ 'LDAPGroupClass' ] ) or 01189 !isset( $requiredParams[ 'LDAPGroupNameAttribute' ] ) or empty( $requiredParams[ 'LDAPGroupNameAttribute' ] ) or 01190 !isset( $requiredParams[ 'LDAPGroupMemberAttribute' ] ) or empty( $requiredParams[ 'LDAPGroupMemberAttribute' ] ) or 01191 !isset( $requiredParams[ 'ds' ] ) or !$requiredParams[ 'ds' ] ) 01192 { 01193 eZDebug::writeError( 'Missing one of required parameters.', 01194 $thisFunctionErrorLabel ); 01195 return false; 01196 } 01197 if ( !isset( $groupsTree[ $curDN ] ) ) 01198 { 01199 eZDebug::writeError( 'Passed $curDN is not in result tree array. Algorithm\'s usage error.', 01200 $thisFunctionErrorLabel ); 01201 return false; 01202 } 01203 array_push( $stack, $curDN ); 01204 01205 $LDAPGroupBaseDN =& $requiredParams[ 'LDAPGroupBaseDN' ]; 01206 $LDAPGroupClass =& $requiredParams[ 'LDAPGroupClass' ]; 01207 $LDAPGroupNameAttribute =& $requiredParams[ 'LDAPGroupNameAttribute' ]; 01208 $LDAPGroupMemberAttribute =& $requiredParams[ 'LDAPGroupMemberAttribute' ]; 01209 $LDAPGroupDescriptionAttribute =& $requiredParams[ 'LDAPGroupDescriptionAttribute' ]; 01210 $ds =& $requiredParams[ 'ds' ]; 01211 01212 $current =& $groupsTree[ $curDN ]; 01213 01214 $retrieveAttributes = array( $LDAPGroupNameAttribute, 01215 $LDAPGroupMemberAttribute ); 01216 $sr = ldap_search( $ds, $LDAPGroupBaseDN, $filter, $retrieveAttributes ); 01217 $entries = ldap_get_entries( $ds, $sr ); 01218 01219 if ( is_array( $entries ) and 01220 isset( $entries[ 'count' ] ) and $entries[ 'count' ] > 0 ) 01221 { 01222 $newfilter = '(&(objectClass=' . $LDAPGroupClass . ')'; 01223 01224 for ( $i = 0; $i < $entries[ 'count' ]; $i++ ) 01225 { 01226 $parent =& $entries[ $i ]; 01227 if ( is_null( $parent ) ) 01228 continue; 01229 01230 $parentDN =& $parent['dn']; 01231 if ( in_array( $parentDN, $stack ) ) 01232 { 01233 $requiredParams[ 'LDAPGroupNameAttribute' ]; 01234 01235 eZDebug::writeError( 'Recursion is detected in the user-groups tree while getting parent groups for ' . $curDN, 01236 $thisFunctionErrorLabel ); 01237 $groupsTree[ '_recursion_detected_' ] = true; 01238 return false; 01239 } 01240 01241 if ( !isset( $groupsTree[ $parentDN ] ) ) 01242 { 01243 $groupsTree[ $parentDN ] = array( 'data' => $parent, 01244 'parents' => array(), 01245 'children' => array() ); 01246 } 01247 $groupsTree[ $parentDN ][ 'children' ][ $curDN ] =& $current; 01248 $current[ 'parents' ][ $parentDN ] =& $groupsTree[ $parentDN ]; 01249 $newfilter1 = $newfilter . '(' . $LDAPGroupMemberAttribute . '=' . $parentDN . '))'; 01250 $ret = eZLDAPUser::getUserGroupsTree( $requiredParams, 01251 $newfilter1, 01252 $parentDN, 01253 $groupsTree, 01254 $stack, 01255 $depth - 1 ); 01256 if ( isset( $groupsTree[ '_recursion_detected_' ] ) and 01257 $groupsTree[ '_recursion_detected_' ] ) 01258 { 01259 return false; 01260 } 01261 } 01262 } 01263 else 01264 { 01265 // We've reached a top node 01266 if ( !isset( $groupsTree[ 'root' ] ) ) 01267 { 01268 $groupsTree[ 'root' ] = array( 'data' => null, 01269 'parents' => null, 01270 'children' => array(), 01271 'nodes' => array( $requiredParams[ 'TopUserGroupNodeID' ] ) ); 01272 } 01273 if ( !isset( $groupsTree[ 'root' ][ 'children' ][ $curDN ] ) ) 01274 $groupsTree[ 'root' ][ 'children' ][ $curDN ] =& $current; 01275 if ( !isset( $current[ 'parents' ][ 'root' ] ) ) 01276 $current[ 'parents' ][ 'root' ] =& $groupsTree[ 'root' ]; 01277 } 01278 01279 array_pop( $stack ); 01280 return true; 01281 } 01282 01283 01284 } 01285 01286 ?>