Changeset 284 for trunk/contactcenter/inc/class.bo_ldap_manager.inc.php
- Timestamp:
- 05/21/08 16:56:17 (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/contactcenter/inc/class.bo_ldap_manager.inc.php
r23 r284 12 12 \***************************************************************************/ 13 13 14 14 15 15 /* 16 16 This class is responsible for the LDAP control/generic functions and for 17 17 configuration gathering 18 18 */ 19 20 class bo_ldap_manager 19 include_once('class.Thread.inc.php'); 20 21 class bo_ldap_manager 21 22 { 22 23 23 24 var $srcs; 24 25 25 26 26 function bo_ldap_manager () 27 27 { 28 28 29 if (!($this->srcs = $GLOBALS['phpgw']->session->appsession('bo_ldap_manager.srcs','contactcenter'))) 29 30 { 30 31 $c = CreateObject('phpgwapi.config','contactcenter'); 31 32 $data = $c->read_repository(); 32 33 33 34 if (!$data or $data['cc_global_source0'] !== 'ldap') 34 35 { … … 36 37 return; 37 38 } 38 39 39 40 $this->srcs = array( 40 41 1 => array( … … 47 48 'branch' => strtolower('ou') 48 49 ) 50 49 51 ); 50 52 } … … 54 56 { 55 57 } 56 58 57 59 /* 58 60 59 61 @function get_all_ldap_sources 60 62 @abstract Returns an array containing all LDAP sources informations 61 63 @author Raphael Derosso Pereira 62 64 63 65 @return array All LDAP information 64 66 $return = array( … … 67 69 'dn' => (string), 68 70 'acc' => (string), 69 'pw' => (string) 71 'pw' => (string) 70 72 ), 71 73 ... 72 74 ) 73 75 74 76 TODO: Return multiple sources... 75 77 */ … … 78 80 return $this->srcs; 79 81 } 80 82 83 /* 84 * @function get_external_ldap_sources 85 * @author Mário César Kolling <mario.kolling@serpro.gov.br> 86 * @abstract returns an array with the external sources 87 * @return (array) the external sources 88 */ 89 90 function get_external_ldap_sources() 91 { 92 include(PHPGW_INCLUDE_ROOT . '/contactcenter/setup/external_catalogs.inc.php' ); 93 //include('external_catalogs.inc.php' ); 94 return $external_srcs; 95 } 96 97 /* 98 * @function get_ldap_fields_association 99 * @abstract get the fields associantion for ldap source 100 * @return an array with attribute mappings 101 */ 81 102 function get_ldap_fields_association ( $id_source ) 82 103 { 83 104 84 105 $op_iop = array( 85 106 'contact.id_contact' => array('dn'), … … 90 111 'contact.family_names' => array('sn'), 91 112 'contact.names_ordered' => array('cn'),//,'displayName'), 113 92 114 'contact.suffixes.suffix' => false, 93 115 'contact.birthdate' => false, … … 95 117 'contact.pgp_key' => false, 96 118 'contact.notes' => false, 97 'contact.mail_forwarding_address' => array('mailForwardingAddress'), 98 'contact.account_type' => array('phpgwAccountType'), 119 'contact.mail_forwarding_address' => array('mailForwardingAddress'), 120 'contact.account_type' => array('phpgwAccountType'), 121 'contact.account_status' => array('phpgwAccountStatus'), 122 'contact.account_visible' => array('phpgwAccountVisible'), 123 'contact.object_class' => array('objectClass'), 99 124 'contact.business_info.title' => array('title'), 100 'contact.business_info.department' => array('ou'), 125 'contact.business_info.department' => array('ou'), // Setor do empregado... 126 'contact.business_info.empNumber' => array('employeeNumber'), // Matricula do empregado 101 127 'contact.company.company_name' => array('o'), 102 128 'contact.company.company_notes' => array('businessCategory'), 103 129 104 130 'contact.contact_related.names_ordered' => 'contact.contact_related.typeof_relation.contact_relation_name', 105 131 'contact.contact_related.typeof_relation.contact_relation_name' => array( … … 107 133 'secretary' => array('secretary') 108 134 ), 109 135 110 136 'contact.address.address1' => 'contact.address.typeof_address.contact_address_type_name', 111 137 'contact.address.typeof_address.contact_address_type_name' => array( 112 138 'home' => array('street', 'st', 'postalAddress', 'homePostalAddress'), 113 139 ), 114 140 115 141 'contact.address.postal_code' => 'contact.address.typeof_address.contact_address_type_name', 116 142 'contact.address.typeof_address.contact_address_type_name' => array( 117 143 'home' => array('PostalCode'), 118 144 ), 119 145 120 146 'contact.address.city.city_name' => 'contact.address.typeof_address.contact_address_type_name', 121 147 'contact.address.typeof_address.contact_address_type_name' => array( 122 148 'home' => array('l'), 123 149 ), 124 150 125 151 'contact.address.city.state.state_name' => 'contact.address.typeof_address.contact_address_type_name', 126 152 'contact.address.typeof_address.contact_address_type_name' => array( 127 153 'home' => false, 128 154 ), 129 155 130 156 'contact.address.city.country.id_country' => 'contact.address.typeof_address.contact_address_type_name', 131 157 'contact.address.typeof_address.contact_address_type_name' => array( 132 158 'home' => array('c') 133 159 ), 134 160 135 161 'contact.connection.connection_value' => 'contact.connection.typeof_connection.contact_connection_type_name', 136 162 'contact.connection.typeof_connection.contact_connection_type_name' => array ( … … 143 169 ), 144 170 ); 145 171 146 172 return $op_iop; 173 174 } 175 176 /* 177 * @function get_external_ldap_fields_association 178 * @author Mário César Kolling <mario.kolling@serpro.gov.br> 179 * @abstract get the fields association for an external ldap_source 180 * @return an array with attribute mappings 181 */ 182 function get_external_ldap_fields_association ( $id_source ) 183 { 184 include(PHPGW_INCLUDE_ROOT . '/contactcenter/setup/external_catalogs.inc.php' ); 185 //include('external_catalogs.inc.php' ); 186 return $external_mappings[$id_source]; 187 } 188 189 /* 190 * @function test_connection 191 * @author Mário César Kolling <mario.kolling@serpro.gov.br> 192 * @abstract Test if we can bind to a ldap server in a reasonable time 193 * @param (string) $host ldap server's hostname 194 * @param (string) $account ldap bind dn 195 * @param (string) $password a bind dn's password 196 * @return (array) an array with the answer from the subprocess, null otherwise 197 */ 198 function test_connection($host, $account, $password, $timeout = 5) 199 { 200 //opens a subprocess for nonblocking bind 201 $tsearch = Thread::Create('class.ldap_assync.inc.php', array('host' => $host, 202 'account' => $account, 203 'password' => $password 204 ) 205 ); 206 207 // It's problably more efficient to let method readResponse control the timeout through 208 // stream_select native timeout. 209 $response = NULL; 210 for ($i = 0; $i < $timeout; $i++) 211 { 212 if ($tsearch->isActive()) 213 { 214 sleep(1); 215 if (($response = $tsearch->readResponse()) !== NULL) 216 { 217 $tsearch->close(); 218 return $response; 219 } 220 221 } 222 else 223 { 224 $response = $tsearch->readResponse(); 225 break; 226 } 227 } 228 229 $tsearch->close(); 230 return null; 147 231 } 148 232 149 233 /*! 150 234 151 235 @function get_ldap_tree 152 236 @abstract Returns the LDAP tree corresponding to the specified level 153 237 @author Raphael Derosso Pereira 154 238 155 239 @param (integer) $id_source The ID of the LDAP source 156 240 157 241 @param (string) $context The context to be used as root branch 158 242 159 243 @param (boolean) $recursive Make it a recursive construction. 160 244 CAUTION! This is EXTREMELY SLOW on large LDAP databases, 161 245 specially when they're not indexed 162 */ 163 function get_ldap_tree($id_source, $context = false, $recursive = false) 246 */ 247 function get_ldap_tree($id_source, $context = false, $recursive = false) 164 248 { 165 249 if (!$this->srcs[$id_source]) … … 167 251 return null; 168 252 } 169 253 170 254 $ldap = $GLOBALS['phpgw']->common->ldapConnect($this->srcs[$id_source]['host'], $this->srcs[$id_source]['acc'],$this->srcs[$id_source]['pw'], false); 171 255 if (!$ldap) … … 173 257 return false; 174 258 } 175 259 176 260 if ($recursive) 177 261 { … … 181 265 return $tree; 182 266 } 183 184 return $this->get_ldap_tree_level($id_source, $ldap, $context, $this->srcs[$id_source]['obj'],$this->srcs[$id_source]['branch']); 185 } 186 267 268 return $this->get_ldap_tree_level($id_source, $ldap, $context, $this->srcs[$id_source]['obj'],$this->srcs[$id_source]['branch'], 0); 269 } 270 271 /*! 272 273 @function get_external_ldap_tree 274 @abstract Returns the LDAP external tree corresponding to the specified level 275 @author Mário César Kolling <mario.kolling@serpro.gov.br> 276 @param (integer) $id_source The ID of the external LDAP source 277 @param (string) $context The context to be used as root branch 278 @param (boolean) $recursive Make it a recursive construction. 279 CAUTION! This is EXTREMELY SLOW on large LDAP databases, 280 specially when they're not indexed 281 */ 282 function get_external_ldap_tree($id_source, $context = false, $recursive = false) 283 { 284 285 286 include(PHPGW_INCLUDE_ROOT . '/contactcenter/setup/external_catalogs.inc.php' ); 287 //include('external_catalogs.inc.php' ); 288 289 if (!$external_srcs[$id_source]) 290 { 291 return null; 292 } 293 294 // calls test_connection first. If succeeded continue, return error message otherwise. 295 if (!($response = $this->test_connection($external_srcs[$id_source]['host'], $external_srcs[$id_source]['acc'], $external_srcs[$id_source]['pw'], 10))) 296 { 297 return array( 298 'msg' => lang("Catalog %1 temporarily unavailable. Please try again later!", $external_srcs[$id_source]['name']), 299 'timeout' => 'true' 300 ); 301 } 302 303 $ldap = $GLOBALS['phpgw']->common->ldapConnect($external_srcs[$id_source]['host'], $external_srcs[$id_source]['acc'],$external_srcs[$id_source]['pw'], false); 304 if (!$ldap) 305 { 306 return false; 307 } 308 309 // Option recursive commented out 310 /* 311 if ($recursive) 312 { 313 $tree = $this->get_ldap_tree_recursive($ldap, $context, $this->srcs[$id_source]['obj'],$this->srcs[$id_source]['branch']); 314 $tree['recursive'] = true; 315 316 return $tree; 317 } 318 */ 319 320 return $this->get_ldap_tree_level($id_source, $ldap, $context, $external_srcs[$id_source]['obj'],$external_srcs[$id_source]['branch'], 1); 321 } 187 322 188 323 /*! … … 201 336 return null; 202 337 } 203 338 204 339 $count = ldap_count_entries($resource,$result_res); 205 340 if ( $count == 0 ) … … 218 353 } 219 354 } 220 355 221 356 $entries = ldap_get_entries($resource, $result_res); 222 357 223 358 for ($i = 0; $i < $entries['count']; $i++) 224 359 { 225 360 $subtree = $this->get_ldap_tree_recursive($resource, $entries[$i]['dn'], $objectClass); 226 361 227 362 $dn_parts=ldap_explode_dn($entries[$i]['dn'],1); 228 229 if ($subtree !== null and is_array($subtree)) 363 364 365 366 if ($subtree !== null and is_array($subtree)) 230 367 { 231 368 $tree[$i]['name'] = $dn_parts[0]; … … 244 381 'sub_branch' => false 245 382 ); 246 } 383 } 247 384 } 248 385 … … 256 393 } 257 394 } 258 395 259 396 function get_ldap_referrals($ds, $dn, $filter) { 260 397 261 398 ldap_set_option($ds, LDAP_OPT_REFERRALS, 0); 262 399 ldap_set_option($ds,LDAP_OPT_PROTOCOL_VERSION,3); 263 400 264 401 if ($ds) { 265 402 ldap_bind($ds); 266 $sr=ldap_list($ds,$dn, $filter); 403 $sr=ldap_list($ds,$dn, $filter); 267 404 $ref = ldap_first_reference($ds, $sr); 268 405 $array_referral = array(); 269 406 $idx = 0; 270 407 271 408 while ($ref) { 272 409 $array_referral[$idx++] = ldap_get_dn($ds, $ref); … … 275 412 return $array_referral; 276 413 } 277 else 414 else 278 415 return false; 279 416 } 280 417 281 418 function get_ldap_sub_branches_referrals($ds, $dn, $filter) { 282 419 283 420 $referral = $this -> get_ldap_referrals($ds, $dn, $filter); 284 421 $sub_branches = array(); 285 422 286 423 for($i = 0; $i <count($referral); $i++) { 287 424 $dn = str_replace("??base","",preg_replace('!^(ldap://[^/]+)/(.*$)!', '\\2', $referral[$i])); 288 $dn = explode(",",$dn); 425 $dn = explode(",",$dn); 289 426 $dn = strtoupper(str_replace("ou=", "",$dn[0])); 290 427 $dn = str_replace("DC=", "",$dn); 291 428 292 429 $sub_branch = array( 293 430 'name' => $dn, 294 431 'type' => 'unknown', 295 432 'value' => $referral[$i], 296 'sub_branch' => false 297 ); 298 $sub_branches[$i] = $sub_branch; 433 'sub_branch' => false 434 ); 435 $sub_branches[$i] = $sub_branch; 299 436 } 300 437 return $sub_branches; 301 438 } 302 303 304 function get_ldap_tree_level($id_source, $resource, $context, $objectClass, $branch_dn) 439 440 function translate_accentuation($text) 441 { 442 /* 443 * Esta operação resolve o problema causado pela conversão de caracteres acentuados realizada 444 * pela função ldap_explode_dn(). 445 */ 446 447 return utf8_decode(preg_replace("/\\\([0-9A-Fa-f]{2})/e", "''.chr(hexdec('\\1')).''", $text)); 448 } 449 450 function get_ldap_tree_level($id_source, $resource, $context, $objectClass, $branch_dn, $external = 0) 305 451 { 306 452 if(strstr($context, "ldap://")){ 307 $refer_context = str_replace("??base","",preg_replace('!^(ldap://[^/]+)/(.*$)!', '\\2', $context)); 308 $host = preg_replace('!^(ldap://[^/]+)/.*$!', '\\1', $context); 453 $refer_context = str_replace("??base","",preg_replace('!^(ldap://[^/]+)/(.*$)!', '\\2', $context)); 454 $host = preg_replace('!^(ldap://[^/]+)/.*$!', '\\1', $context); 309 455 $resource = ldap_connect($host); 310 ldap_bind($resource); 311 } 312 $dn_parts = ldap_explode_dn(($refer_context ? $refer_context : $context),1); 456 ldap_bind($resource); 457 } 458 459 /* 460 * TODO: Search timeouts 461 */ 462 463 $dn_parts = ldap_explode_dn(($refer_context ? $refer_context : $context),1); 313 464 //$filter = '(!(objectClass='.$objectClass.'))'; 314 465 // Don't show OU's whith phpgwAccountVisible equal to '-1' 315 $filter = '(&(!(objectClass='.$objectClass.')) (!(phpgwAccountVisible=-1)))'; 316 $result_res = @ldap_list($resource, ($refer_context ? $refer_context : $context), $filter); 466 467 if ($external) 468 { 469 // external source: get all organizationalUnits 470 $filter = '(objectClass=organizationalUnit)'; 471 } 472 else 473 { 474 // get any objectClass except the objectClass used for the source 475 // and whose attribute phpgwAccountVisible value is different from -1 476 $filter = '(&(!(objectClass='.$objectClass.')) (!(phpgwAccountVisible=-1)))'; 477 } 478 $result_res = @ldap_list($resource, ($refer_context ? $refer_context : $context), $filter, array(), 0, 0); 317 479 @ldap_sort($resource, $result_res, 'ou'); 318 480 481 // Timeouts commented out 482 /* 319 483 if ($result_res === false) 320 484 { 485 if (ldap_errno($resource) === 3) 486 { 487 return array('error_msg' => ldap_error($resource)); 488 } 321 489 return null; 322 490 } 491 */ 323 492 324 493 $count = ldap_count_entries($resource,$result_res); … … 326 495 if ( $count == 0 ) 327 496 { 328 $filter = 'objectClass='.$objectClass; 329 $result_res2 = @ldap_list($resource, ($refer_context ? $refer_context : $context), $filter); 497 $filter = '(objectClass='.$objectClass.')'; 498 // Get only one attribute of the source's objectClass 499 $result_res2 = @ldap_list($resource, ($refer_context ? $refer_context : $context), $filter, Array('cn'), 0, 1); 330 500 $entries_count = ldap_count_entries($resource, $result_res2); 331 501 … … 333 503 { 334 504 return array( 335 'name' => $ dn_parts[0],505 'name' => $this->translate_accentuation($dn_parts[0]), 336 506 'type' => 'catalog', 337 507 'class' => 'bo_global_ldap_catalog', 338 'class_args' => array($id_source, $context), 508 // Pass the variable $external as a parameter to the constructor 509 'class_args' => array($id_source, $context, $external), 339 510 'icon' => 'globalcatalog-mini.png', 340 511 'value' => $context, … … 345 516 { 346 517 return array( 347 'name' => $ dn_parts[0],518 'name' => $this->translate_accentuation($dn_parts[0]), 348 519 'type' => 'empty' 349 520 ); … … 361 532 $dn_parts_full = ldap_explode_dn($dn,0); 362 533 list($group) = explode('=',$dn_parts_full[0]); 363 364 if ($group == $branch_dn or $branch_dn === 'all') 534 535 //Faz a comparação do branch como case insensitive 536 if (strtolower($group) == strtolower($branch_dn) or $branch_dn === 'all') 365 537 { 366 538 $tree['sub_branch'][$i] = array( 367 'name' => $ dn_parts_1[0],539 'name' => $this->translate_accentuation($dn_parts_1[0]), 368 540 'type' => 'unknown', 369 541 'value' => ($refer_context ? $host."/" : "").$dn, 370 'sub_branch' => false 542 'sub_branch' => false 371 543 ); 372 544 $sub_branch_found = true; … … 374 546 $i++; 375 547 } 376 548 377 549 if(! $refer_context) { 378 550 $array_referral = $this -> get_ldap_sub_branches_referrals($resource, $context,'(objectClass=organizationalUnit)'); … … 383 555 384 556 $filter = 'objectClass='.$objectClass; 385 $result_res2 = @ldap_list($resource, ($refer_context ? $refer_context : $context), $filter );557 $result_res2 = @ldap_list($resource, ($refer_context ? $refer_context : $context), $filter, Array('cn'), 0, 1); 386 558 $entries_count = ldap_count_entries($resource, $result_res2); 387 559 388 560 if ($result_res2 !== false && $entries_count > 0 && $sub_branch_found) 389 561 { 390 $tree['name'] = $ dn_parts[0];562 $tree['name'] = $this->translate_accentuation($dn_parts[0]); 391 563 $tree['type'] = 'mixed_catalog_group'; 392 564 $tree['class'] = 'bo_global_ldap_catalog'; 393 $tree['class_args'] = array($id_source,$context); 565 // Pass the variable $external as a parameter to the constructor 566 $tree['class_args'] = array($id_source,$context,$external); 394 567 $tree['icon'] = 'globalcatalog-mini.png'; 395 568 $tree['value'] = $context; … … 398 571 { 399 572 return array( 400 'name' => $ dn_parts[0],573 'name' => $this->translate_accentuation($dn_parts[0]), 401 574 'type' => 'catalog', 402 575 'class' => 'bo_global_ldap_catalog', 403 'class_args' => array($id_source, $context), 576 // Pass the variable $external as a parameter to the constructor 577 'class_args' => array($id_source, $context,$external), 404 578 'icon' => 'globalcatalog-mini.png', 405 579 'value' => $context, … … 409 583 else 410 584 { 411 $tree['name'] = $ dn_parts[0];585 $tree['name'] = $this->translate_accentuation($dn_parts[0]); 412 586 $tree['type'] = 'catalog_group'; 413 587 $tree['class'] = 'bo_catalog_group_catalog'; 414 $tree['class_args'] = array('$this', '$this->get_branch_by_level($this->catalog_level[0])'); 588 // Pass the variable $external as a parameter to the constructor 589 $tree['class_args'] = array('$this', '$this->get_branch_by_level($this->catalog_level[0])', $external); 415 590 $tree['value'] = $context; 416 591 $tree['ldap'] = array('id_source' => $id_source, 'context' => $context); 417 592 } 418 419 593 usort($tree['sub_branch'], array($this, "compareTreeNodes")); 420 594 return $tree; … … 422 596 423 597 function compareTreeNodes($a, $b) { 424 598 425 599 return strnatcasecmp($a['name'], $b['name']); 426 } 600 } 427 601 428 602 }
Note: See TracChangeset
for help on using the changeset viewer.