source: trunk/contactcenter/inc/class.bo_ldap_manager.inc.php @ 333

Revision 333, 18.2 KB checked in by niltonneto, 16 years ago (diff)

Alteração no código para não gerar erro no log, quando não encontra
nenhum resultado ou há problema momentâneo de conexão.

  • Property svn:eol-style set to native
  • Property svn:executable set to *
Line 
1<?php
2  /***************************************************************************\
3  * eGroupWare - Contacts Center                                              *
4  * http://www.egroupware.org                                                 *
5  * Written by:                                                               *
6  *  - Raphael Derosso Pereira <raphaelpereira@users.sourceforge.net>         *
7  * ------------------------------------------------------------------------- *
8  *  This program is free software; you can redistribute it and/or modify it  *
9  *  under the terms of the GNU General Public License as published by the    *
10  *  Free Software Foundation; either version 2 of the License, or (at your   *
11  *  option) any later version.                                               *
12  \***************************************************************************/
13
14       
15        /*
16                This class is responsible for the LDAP control/generic functions and for
17                configuration gathering
18        */
19        include_once('class.Thread.inc.php');
20
21        class bo_ldap_manager
22        {
23               
24                var $srcs;
25
26               
27                function bo_ldap_manager ()
28                {
29                        if (!($this->srcs = $GLOBALS['phpgw']->session->appsession('bo_ldap_manager.srcs','contactcenter')))
30                        {
31                                $c = CreateObject('phpgwapi.config','contactcenter');
32                                $data = $c->read_repository();
33                               
34                                if (!$data or $data['cc_global_source0'] !== 'ldap')
35                                {
36                                        $this->srcs = null;
37                                        return;
38                                }
39                               
40                                $this->srcs = array(
41                                        1 => array(
42                                                'name'   => $data['cc_catalog_name'],
43                                                'host'   => $data['cc_ldap_host0'],
44                                                'dn'     => $data['cc_ldap_context0'],
45                                                'acc'    => $data['cc_ldap_browse_dn0'],
46                                                'pw'     => $data['cc_ldap_pw0'],
47                                                'obj'    => 'inetOrgPerson',
48                                                'branch' => strtolower('ou'),
49                                                'visible' => $data['cc_ldap_query_automatic']
50                                        )
51                                );
52                        }
53                }
54
55                function new_ldap_source ( $source_name, $charset, $host, $port, $dn_root, $dn_admin, $admin_pass, $contact_objectclass )
56                {
57                }
58       
59                /*
60               
61                        @function get_all_ldap_sources
62                        @abstract Returns an array containing all LDAP sources informations
63                        @author Raphael Derosso Pereira
64               
65                        @return array All LDAP information
66                                $return = array(
67                                        <id_source> => array(
68                                                'host' => (string),
69                                                'dn'   => (string),
70                                                'acc'  => (string),
71                                                'pw'   => (string)   
72                                        ),
73                                        ...
74                                )
75                               
76                        TODO: Return multiple sources...
77                */
78                function get_all_ldap_sources (  )
79                {
80                        return $this->srcs;
81                }
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                 */
102                function get_ldap_fields_association ( $id_source )
103                {
104                       
105                        $op_iop = array(
106                                'contact.id_contact'               => array('dn'),
107                                'contact.photo'                    => array('jpegPhoto'),
108                                'contact.prefixes.prefix'          => false,
109                                'contact.alias'                    => array('alias'),
110                                'contact.given_names'              => array('givenName'),
111                                'contact.family_names'             => array('sn'),
112                                'contact.names_ordered'            => array('cn'),//,'displayName'),
113                                'contact.suffixes.suffix'          => false,
114                                'contact.birthdate'                => false,
115                                'contact.sex'                      => false,
116                                'contact.pgp_key'                  => false,
117                                'contact.notes'                    => false,
118                                'contact.mail_forwarding_address' => array('mailForwardingAddress'),
119                                'contact.account_type' => array('phpgwAccountType'),
120                'contact.account_status'           => array('phpgwAccountStatus'),
121                'contact.account_visible'          => array('phpgwAccountVisible'),
122                                'contact.object_class'             => array('objectClass'),
123                                'contact.business_info.title'      => array('title'),
124                                'contact.business_info.department' => array('ou'),
125                                'contact.company.company_name'     => array('o'),
126                                'contact.company.company_notes'    => array('businessCategory'),
127                               
128                                'contact.contact_related.names_ordered' => 'contact.contact_related.typeof_relation.contact_relation_name',
129                                'contact.contact_related.typeof_relation.contact_relation_name' =>  array(
130                                        'manager'   => array('manager'),
131                                        'secretary' => array('secretary')
132                                ),
133                               
134                                'contact.address.address1'         => 'contact.address.typeof_address.contact_address_type_name',
135                                'contact.address.typeof_address.contact_address_type_name' => array(
136                                        'home' => array('street', 'st', 'postalAddress', 'homePostalAddress'),
137                                ),
138                               
139                                'contact.address.postal_code'      => 'contact.address.typeof_address.contact_address_type_name',
140                                'contact.address.typeof_address.contact_address_type_name' => array(
141                                        'home' => array('PostalCode'),
142                                ),
143                               
144                                'contact.address.city.city_name'   => 'contact.address.typeof_address.contact_address_type_name',
145                                'contact.address.typeof_address.contact_address_type_name' => array(
146                                        'home' => array('l'),
147                                ),
148                               
149                                'contact.address.city.state.state_name'       => 'contact.address.typeof_address.contact_address_type_name',
150                                'contact.address.typeof_address.contact_address_type_name' => array(
151                                        'home' => false,
152                                ),
153                               
154                                'contact.address.city.country.id_country'     => 'contact.address.typeof_address.contact_address_type_name',
155                                'contact.address.typeof_address.contact_address_type_name' => array(
156                                        'home' => array('c')
157                                ),
158                               
159                                'contact.connection.connection_value'         => 'contact.connection.typeof_connection.contact_connection_type_name',
160                                'contact.connection.typeof_connection.contact_connection_type_name' => array (
161                                        'email'  => array('mail'),
162                                        'phone'  => array('telephoneNumber'),
163                                        'mobile' => array('mobile'),
164                                        'pager'  => array('pager'),
165                                        'fax'    => array('facsimileTelephoneNumber'),
166                                        'telex'  => array('telexNumber')
167                                ),
168                        );
169                       
170                        return $op_iop;
171                }
172
173                /*
174                 * @function get_external_ldap_fields_association
175                 * @author Mário César Kolling <mario.kolling@serpro.gov.br>
176                 * @abstract get the fields association for an external ldap_source
177                 * @return an array with attribute mappings
178                 */
179                function get_external_ldap_fields_association ( $id_source )
180                {
181                        include(PHPGW_INCLUDE_ROOT . '/contactcenter/setup/external_catalogs.inc.php' );
182                        //include('external_catalogs.inc.php' );
183                        return $external_mappings[$id_source];
184                }
185
186                /*
187                 * @function test_connection
188                 * @author Mário César Kolling <mario.kolling@serpro.gov.br>
189                 * @abstract Test if we can bind to a ldap server in a reasonable time
190                 * @param (string) $host ldap server's hostname
191                 * @param (string) $account ldap bind dn
192                 * @param (string) $password a bind dn's password
193                 * @return (array) an array with the answer from the subprocess, null otherwise
194                 */
195                function test_connection($host, $account, $password, $timeout = 5)
196                {
197                        //opens a subprocess for nonblocking bind
198                        $tsearch = Thread::Create('class.ldap_assync.inc.php', array('host'     => $host,
199                                                                                                                                'account'       => $account,
200                                                                                                                                'password'      => $password
201                                                                                                                                )
202                        );
203
204                        // It's problably more efficient to let method readResponse control the timeout through
205                        // stream_select native timeout.
206                        $response = NULL;
207                        for ($i = 0; $i < $timeout; $i++)
208                        {
209                                if ($tsearch->isActive())
210                                {
211                                        sleep(1);
212                                        if (($response = $tsearch->readResponse()) !== NULL)
213                                        {
214                                                $tsearch->close();
215                                                return $response;
216                                        }
217
218                                }
219                                else
220                                {
221                                        $response = $tsearch->readResponse();
222                                        break;
223                                }
224                        }
225
226                        $tsearch->close();
227                        return null;
228                }
229
230                /*!
231               
232                        @function get_ldap_tree
233                        @abstract Returns the LDAP tree corresponding to the specified level
234                        @author Raphael Derosso Pereira
235                       
236                        @param (integer) $id_source The ID of the LDAP source
237                       
238                        @param (string)  $context The context to be used as root branch
239                               
240                        @param (boolean) $recursive Make it a recursive construction.
241                                CAUTION! This is EXTREMELY SLOW on large LDAP databases,
242                                specially when they're not indexed
243                */             
244                function get_ldap_tree($id_source, $context = false, $recursive = false)
245                {
246                        if (!$this->srcs[$id_source])
247                        {
248                                return null;
249                        }
250                       
251                        $ldap = $GLOBALS['phpgw']->common->ldapConnect($this->srcs[$id_source]['host'], $this->srcs[$id_source]['acc'],$this->srcs[$id_source]['pw'], true);
252                        if (!$ldap)
253                        {
254                                return false;
255                        }
256                       
257                        if ($recursive)
258                        {
259                                $tree = $this->get_ldap_tree_recursive($ldap, $context, $this->srcs[$id_source]['obj'],$this->srcs[$id_source]['branch']);
260                                $tree['recursive'] = true;
261
262                                return $tree;
263                        }
264                       
265                        return $this->get_ldap_tree_level($id_source, $ldap, $context, $this->srcs[$id_source]['obj'],$this->srcs[$id_source]['branch']);
266                }
267                // SERPRO
268
269                /*!
270
271                        @function get_external_ldap_tree
272                        @abstract Returns the LDAP external tree corresponding to the specified level
273                        @author Mário César Kolling <mario.kolling@serpro.gov.br>
274                        @param (integer) $id_source The ID of the external LDAP source
275                        @param (string)  $context The context to be used as root branch
276                        @param (boolean) $recursive Make it a recursive construction.
277                                CAUTION! This is EXTREMELY SLOW on large LDAP databases,
278                                specially when they're not indexed
279                */
280                function get_external_ldap_tree($id_source, $context = false, $recursive = false)
281                {
282
283
284                        include(PHPGW_INCLUDE_ROOT . '/contactcenter/setup/external_catalogs.inc.php' );
285                        //include('external_catalogs.inc.php' );
286
287                        if (!$external_srcs[$id_source])
288                        {
289                                return null;
290                        }
291
292                        // calls test_connection first. If succeeded continue, return error message otherwise.
293                        if (!($response = $this->test_connection($external_srcs[$id_source]['host'], $external_srcs[$id_source]['acc'], $external_srcs[$id_source]['pw'], 10)))
294                        {
295                                return array(
296                                        'msg'           =>      lang("Catalog %1 temporarily unavailable. Please try again later!", $external_srcs[$id_source]['name']),
297                                        'timeout'       =>      'true'
298                                );
299                        }
300
301                        $ldap = $GLOBALS['phpgw']->common->ldapConnect($external_srcs[$id_source]['host'], $external_srcs[$id_source]['acc'],$external_srcs[$id_source]['pw'], false);
302                        if (!$ldap)
303                        {
304                                return false;
305                        }
306
307                        // Option recursive commented out
308                        /*
309                        if ($recursive)
310                        {
311                                $tree = $this->get_ldap_tree_recursive($ldap, $context, $this->srcs[$id_source]['obj'],$this->srcs[$id_source]['branch']);
312                                $tree['recursive'] = true;
313
314                                return $tree;
315                        }
316                        */
317
318                        return $this->get_ldap_tree_level($id_source, $ldap, $context, $external_srcs[$id_source]['obj'],$external_srcs[$id_source]['branch'], 1);
319                }
320
321                /*!
322
323                        THIS FUNCTION IS NOT TESTED AND IS PROBABLY BROKEN!
324                        I WILL CORRECT IT IN THE NEAR FUTURE
325
326                */
327                function get_ldap_tree_recursive($resource, $context, $objectClass)
328                {
329                        $filter = '(!(objectClass='.$objectClass.'))';
330                        $result_res = ldap_list($resource, $context, $filter);
331
332                        if ($result_res === false)
333                        {
334                                return null;
335                        }
336                       
337                        $count = ldap_count_entries($resource,$result_res);
338                        if ( $count == 0 )
339                        {
340                                $filter = 'objectClass='.$objectClass;
341                                $result_res2 = ldap_list($resource, $context, $filter);
342                                $entries_count = ldap_count_entries($resource, $result_res2);
343
344                                if ($result_res2 !== false && $entries_count > 0)
345                                {
346                                        return $entries_count;
347                                }
348                                else
349                                {
350                                        return null;
351                                }
352                        }
353                       
354                        $entries = ldap_get_entries($resource, $result_res);
355                       
356                        for ($i = 0; $i < $entries['count']; $i++)
357                        {
358                                $subtree = $this->get_ldap_tree_recursive($resource, $entries[$i]['dn'], $objectClass);
359                               
360                                $dn_parts=ldap_explode_dn($entries[$i]['dn'],1);
361                               
362                                if ($subtree !== null and is_array($subtree))
363                                {
364                                        $tree[$i]['name'] = $dn_parts[0];
365                                        $tree[$i]['type'] = 'catalog_group';
366                                        $tree[$i]['recursive'] = true;
367                                        $tree[$i]['sub_branch'] = $subtree;
368                                }
369                                else if (is_int($subtree) and $subtree !== null)
370                                {
371                                        $tree[$i] = array(
372                                                'name'       => $dn_parts[0],
373                                                'type'       => 'catalog',
374                                                'class'      => 'global_contact_manager',
375                                                'icon'       => 'share-mini.png',
376                                                'value'      => $entries[$i]['dn'],
377                                                'sub_branch' => false
378                                        );
379                                }
380                        }
381
382                        if (is_array($tree))
383                        {
384                                return $tree;
385                        }
386                        else
387                        {
388                                return null;
389                        }
390                }
391               
392                function get_ldap_referrals($ds, $dn, $filter) {
393                       
394                        ldap_set_option($ds, LDAP_OPT_REFERRALS, 0);
395                        ldap_set_option($ds,LDAP_OPT_PROTOCOL_VERSION,3);
396                       
397                        if ($ds) {
398                            ldap_bind($ds);
399                                $sr=ldap_list($ds,$dn, $filter);                   
400                                $ref = ldap_first_reference($ds, $sr);
401                                $array_referral = array();
402                                $idx = 0;
403                               
404                                 while ($ref) {
405                                        $array_referral[$idx++] = ldap_get_dn($ds, $ref);
406                                        $ref = ldap_next_reference($ds, $ref);
407                                }
408                                return $array_referral;
409                        }
410                        else
411                                return false;
412                       
413                       
414                }
415
416                function get_ldap_sub_branches_referrals($ds, $dn, $filter) {
417                       
418                        $referral = $this -> get_ldap_referrals($ds, $dn, $filter);
419                        $sub_branches = array();
420                       
421                        for($i = 0; $i <count($referral); $i++) {
422                                $dn = str_replace("??base","",preg_replace('!^(ldap://[^/]+)/(.*$)!', '\\2', $referral[$i]));
423                                $dn = explode(",",$dn);                         
424                                $dn = strtoupper(str_replace("ou=", "",$dn[0]));
425                                $dn = str_replace("DC=", "",$dn);
426                                                                                                                                                                               
427                                $sub_branch = array(
428                                                                                        'name' => $dn,
429                                                                'type' => 'unknown',
430                                                                'value' => $referral[$i],
431                                                                'sub_branch' => false           
432                                                                                );                                                                                                                     
433                                $sub_branches[$i] = $sub_branch;                       
434                        }
435                        return $sub_branches;
436                }
437               
438
439                function translate_accentuation($text)
440                {
441                        /*
442                         * Esta operação resolve o problema causado pela conversão de caracteres acentuados realizada
443                         * pela função ldap_explode_dn().
444                         */
445
446                        return utf8_decode(preg_replace("/\\\([0-9A-Fa-f]{2})/e", "''.chr(hexdec('\\1')).''", $text));
447                }
448
449                function get_ldap_tree_level($id_source, $resource, $context, $objectClass, $branch_dn, $external = 0)
450                {
451                                               
452                        /*
453                         * TODO: Search timeouts
454                         */
455                       
456                        $dn_parts = ldap_explode_dn($context,1);
457                        //$filter = '(!(objectClass='.$objectClass.'))';
458                        // Don't show OU's whith phpgwAccountVisible equal to '-1'
459                        if ($external)
460                        {
461                                // external source: get all organizationalUnits
462                                $filter = '(objectClass=organizationalUnit)';
463                        }
464                        else
465                        {
466                                // get any objectClass except the objectClass used for the source
467                                // and whose attribute phpgwAccountVisible value is different from -1
468                                $filter = '(&(!(objectClass='.$objectClass.')) (!(phpgwAccountVisible=-1)))';
469                        }
470                        $result_res = @ldap_list($resource,  $context, $filter, array(), 0, 0);
471                        if (!$result_res)
472                                return null;
473                       
474                        @ldap_sort($resource, $result_res, 'ou');
475                        $count = ldap_count_entries($resource,$result_res);
476                       
477                        if ( $count == 0 )
478                        {
479                                $filter = '(objectClass='.$objectClass.')';
480                                // Get only one attribute of the source's objectClass
481                                $result_res2 = @ldap_list($resource, $context, $filter, Array('cn'), 0, 1);
482                                if (!$result_res2)
483                                        return null;
484
485                                $entries_count = ldap_count_entries($resource, $result_res2);
486
487                                if ($result_res2 !== false && $entries_count > 0)
488                                {
489                                        return array(
490                                                'name'       => $this->translate_accentuation($dn_parts[0]),
491                                                'type'       => 'catalog',
492                                                'class'      => 'bo_global_ldap_catalog',
493                                                // Pass the variable $external as a parameter to the constructor
494                                                'class_args' => array($id_source, $context, $external),
495                                                'icon'       => 'globalcatalog-mini.png',
496                                                'value'      => $context,
497                                                'sub_branch' => false
498                                        );
499                                }
500                                else
501                                {
502                                        return array(
503                                                'name' => $this->translate_accentuation($dn_parts[0]),
504                                                'type' => 'empty'
505                                        );
506                                }
507                        }
508                       
509                        $sub_branch_found = false;
510                        $i = 0;
511                        for ($entry = ldap_first_entry($resource, $result_res);
512                             $entry != false;
513                             $entry = ldap_next_entry($resource, $entry))
514                        {
515                                $dn = ldap_get_dn($resource, $entry);
516                                $dn_parts_1 = ldap_explode_dn($dn,1);
517                                $dn_parts_full = ldap_explode_dn($dn,0);
518                                list($group) = explode('=',$dn_parts_full[0]);
519
520                                //Faz a comparação do branch como case insensitive
521                                if (strtolower($group) == strtolower($branch_dn) or $branch_dn === 'all')
522                                {
523                                        $tree['sub_branch'][$i] = array(
524                                                'name'  => $this->translate_accentuation($dn_parts_1[0]),
525                                                'type'  => 'unknown',
526                                                'value' =>  $dn,
527                                                'sub_branch' => false
528                                        );
529                                        $sub_branch_found = true;
530                                }
531                                $i++;
532                        }
533                                               
534                        $filter = 'objectClass='.$objectClass;
535                        $result_res2 = @ldap_list($resource, $context, $filter, Array('cn'), 0, 1);
536                        $entries_count = ldap_count_entries($resource, $result_res2);
537
538                        if ($result_res2 !== false && $entries_count > 0 && $sub_branch_found)
539                        {
540                                $tree['name']       = $this->translate_accentuation($dn_parts[0]);
541                                $tree['type']       = 'mixed_catalog_group';
542                                $tree['class']      = 'bo_global_ldap_catalog';
543                                // Pass the variable $external as a parameter to the constructor
544                                $tree['class_args'] = array($id_source,$context,$external);
545                                $tree['icon']       = 'globalcatalog-mini.png';
546                                $tree['value']      = $context;
547                        }
548                        elseif ($result_res2 !== false && $entries_count > 0 && !$sub_branch_found)
549                        {
550                                return array(
551                                        'name'       => $this->translate_accentuation($dn_parts[0]),
552                                        'type'       => 'catalog',
553                                        'class'      => 'bo_global_ldap_catalog',
554                                        // Pass the variable $external as a parameter to the constructor
555                                        'class_args' => array($id_source, $context,$external),
556                                        'icon'       => 'globalcatalog-mini.png',
557                                        'value'      => $context,
558                                        'sub_branch' => false
559                                );
560                        }
561                        else
562                        {
563                                $tree['name']       = $this->translate_accentuation($dn_parts[0]);
564                                $tree['type']       = 'catalog_group';
565                                $tree['class']      = 'bo_catalog_group_catalog';
566                                // Pass the variable $external as a parameter to the constructor
567                                $tree['class_args'] = array('$this', '$this->get_branch_by_level($this->catalog_level[0])', $external);
568                                $tree['value']      = $context;
569                                $tree['ldap']       = array('id_source' => $id_source, 'context' => $context);
570                        }
571                       
572                        usort($tree['sub_branch'], array($this, "compareTreeNodes"));
573                        return $tree;
574                }
575
576                function compareTreeNodes($a, $b)       {
577                                               
578                        return strnatcasecmp($a['name'], $b['name']);
579                }       
580
581        }
582?>
Note: See TracBrowser for help on using the repository browser.