Ignore:
Timestamp:
Oct 19, 2011 5:56:06 AM (19 months ago)
Author:
alec
Message:
  • Added 'search_dn_default' variable in ldap config
  • Better handling of situation when search for bind DN doesn't return data
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/roundcubemail/program/include/rcube_ldap.php

    r5339 r5349  
    166166        foreach ($this->prop['hosts'] as $host) 
    167167        { 
    168             $host = idn_to_ascii(rcube_parse_host($host)); 
    169             $this->_debug("C: Connect [$host".($this->prop['port'] ? ':'.$this->prop['port'] : '')."]"); 
     168            $host     = idn_to_ascii(rcube_parse_host($host)); 
     169            $hostname = $host.($this->prop['port'] ? ':'.$this->prop['port'] : ''); 
     170 
     171            $this->_debug("C: Connect [$hostname]"); 
    170172 
    171173            if ($lc = @ldap_connect($host, $this->prop['port'])) 
    172174            { 
    173                 if ($this->prop['use_tls']===true) 
     175                if ($this->prop['use_tls'] === true) 
    174176                    if (!ldap_start_tls($lc)) 
    175177                        continue; 
     
    185187        } 
    186188 
    187         if (is_resource($this->conn)) 
    188         { 
    189             $this->ready = true; 
    190  
    191             $bind_pass = $this->prop['bind_pass']; 
    192             $bind_user = $this->prop['bind_user']; 
    193             $bind_dn   = $this->prop['bind_dn']; 
    194  
    195             $this->base_dn        = $this->prop['base_dn']; 
    196             $this->groups_base_dn = ($this->prop['groups']['base_dn']) ? 
    197                 $this->prop['groups']['base_dn'] : $this->base_dn; 
    198  
    199             // User specific access, generate the proper values to use. 
    200             if ($this->prop['user_specific']) { 
    201                 // No password set, use the session password 
    202                 if (empty($bind_pass)) { 
    203                     $bind_pass = $RCMAIL->decrypt($_SESSION['password']); 
    204                 } 
    205  
    206                 // Get the pieces needed for variable replacement. 
    207                 if ($fu = $RCMAIL->user->get_username()) 
    208                   list($u, $d) = explode('@', $fu); 
    209                 else 
    210                   $d = $this->mail_domain; 
    211  
    212                 $dc = 'dc='.strtr($d, array('.' => ',dc=')); // hierarchal domain string 
    213  
    214                 $replaces = array('%dc' => $dc, '%d' => $d, '%fu' => $fu, '%u' => $u); 
    215  
    216                 if ($this->prop['search_base_dn'] && $this->prop['search_filter']) { 
    217                     // Search for the dn to use to authenticate 
    218                     $this->prop['search_base_dn'] = strtr($this->prop['search_base_dn'], $replaces); 
    219                     $this->prop['search_filter'] = strtr($this->prop['search_filter'], $replaces); 
    220  
    221                     $this->_debug("S: searching with base {$this->prop['search_base_dn']} for {$this->prop['search_filter']}"); 
    222  
    223                     $res = @ldap_search($this->conn, $this->prop['search_base_dn'], $this->prop['search_filter'], array('uid')); 
    224                     if ($res && ($entry = ldap_first_entry($this->conn, $res))) { 
    225                         $bind_dn = ldap_get_dn($this->conn, $entry); 
    226  
    227                         $this->_debug("S: search returned dn: $bind_dn"); 
    228  
    229                         if ($bind_dn) { 
    230                             $dn = ldap_explode_dn($bind_dn, 1); 
    231                             $replaces = array('%dn' => $dn[0]) + $replaces; 
    232                         } 
    233                     } 
    234                 } 
    235                 // Replace the bind_dn and base_dn variables. 
    236                 $bind_dn              = strtr($bind_dn, $replaces); 
    237                 $this->base_dn        = strtr($this->base_dn, $replaces); 
    238                 $this->groups_base_dn = strtr($this->groups_base_dn, $replaces); 
    239  
    240                 if (empty($bind_user)) { 
    241                     $bind_user = $u; 
    242                 } 
    243             } 
    244  
    245             if (!empty($bind_pass)) { 
    246                 if (!empty($bind_dn)) { 
    247                     $this->ready = $this->bind($bind_dn, $bind_pass); 
    248                 } 
    249                 else if (!empty($this->prop['auth_cid'])) { 
    250                     $this->ready = $this->sasl_bind($this->prop['auth_cid'], $bind_pass, $bind_user); 
    251                 } 
    252                 else { 
    253                     $this->ready = $this->sasl_bind($bind_user, $bind_pass); 
    254                 } 
    255             } 
    256         } 
    257         else 
    258             raise_error(array('code' => 100, 'type' => 'ldap', 
    259                 'file' => __FILE__, 'line' => __LINE__, 
    260                 'message' => "Could not connect to any LDAP server, last tried $host:{$this->prop[port]}"), true); 
    261  
    262189        // See if the directory is writeable. 
    263190        if ($this->prop['writable']) { 
    264191            $this->readonly = false; 
    265         } // end if 
     192        } 
     193 
     194        if (!is_resource($this->conn)) { 
     195            raise_error(array('code' => 100, 'type' => 'ldap', 
     196                'file' => __FILE__, 'line' => __LINE__, 
     197                'message' => "Could not connect to any LDAP server, last tried $hostname"), true); 
     198 
     199            return false; 
     200        } 
     201 
     202        $bind_pass = $this->prop['bind_pass']; 
     203        $bind_user = $this->prop['bind_user']; 
     204        $bind_dn   = $this->prop['bind_dn']; 
     205 
     206        $this->base_dn        = $this->prop['base_dn']; 
     207        $this->groups_base_dn = ($this->prop['groups']['base_dn']) ? 
     208        $this->prop['groups']['base_dn'] : $this->base_dn; 
     209 
     210        // User specific access, generate the proper values to use. 
     211        if ($this->prop['user_specific']) { 
     212            // No password set, use the session password 
     213            if (empty($bind_pass)) { 
     214                $bind_pass = $RCMAIL->decrypt($_SESSION['password']); 
     215            } 
     216 
     217            // Get the pieces needed for variable replacement. 
     218            if ($fu = $RCMAIL->user->get_username()) 
     219                list($u, $d) = explode('@', $fu); 
     220            else 
     221                $d = $this->mail_domain; 
     222 
     223            $dc = 'dc='.strtr($d, array('.' => ',dc=')); // hierarchal domain string 
     224 
     225            $replaces = array('%dn' => '', '%dc' => $dc, '%d' => $d, '%fu' => $fu, '%u' => $u); 
     226 
     227            if ($this->prop['search_base_dn'] && $this->prop['search_filter']) { 
     228                // Search for the dn to use to authenticate 
     229                $this->prop['search_base_dn'] = strtr($this->prop['search_base_dn'], $replaces); 
     230                $this->prop['search_filter'] = strtr($this->prop['search_filter'], $replaces); 
     231 
     232                $this->_debug("S: searching with base {$this->prop['search_base_dn']} for {$this->prop['search_filter']}"); 
     233 
     234                $res = @ldap_search($this->conn, $this->prop['search_base_dn'], $this->prop['search_filter'], array('uid')); 
     235                if ($res) { 
     236                    if (($entry = ldap_first_entry($this->conn, $res)) 
     237                        && ($bind_dn = ldap_get_dn($this->conn, $entry)) 
     238                    ) { 
     239                        $this->_debug("S: search returned dn: $bind_dn"); 
     240                        $dn = ldap_explode_dn($bind_dn, 1); 
     241                        $replaces['%dn'] = $dn[0]; 
     242                    } 
     243                } 
     244                else { 
     245                    $this->_debug("S: ".ldap_error($this->conn)); 
     246                } 
     247 
     248                // DN not found 
     249                if (empty($replaces['%dn'])) { 
     250                    if (!empty($this->prop['search_dn_default'])) 
     251                        $replaces['%dn'] = $this->prop['search_dn_default']; 
     252                    else { 
     253                        raise_error(array( 
     254                            'code' => 100, 'type' => 'ldap', 
     255                            'file' => __FILE__, 'line' => __LINE__, 
     256                            'message' => "DN not found using LDAP search."), true); 
     257                        return false; 
     258                    } 
     259                } 
     260            } 
     261 
     262            // Replace the bind_dn and base_dn variables. 
     263            $bind_dn              = strtr($bind_dn, $replaces); 
     264            $this->base_dn        = strtr($this->base_dn, $replaces); 
     265            $this->groups_base_dn = strtr($this->groups_base_dn, $replaces); 
     266 
     267            if (empty($bind_user)) { 
     268                $bind_user = $u; 
     269            } 
     270        } 
     271 
     272        if (empty($bind_pass)) { 
     273            $this->ready = true; 
     274        } 
     275        else { 
     276            if (!empty($bind_dn)) { 
     277                $this->ready = $this->bind($bind_dn, $bind_pass); 
     278            } 
     279            else if (!empty($this->prop['auth_cid'])) { 
     280                $this->ready = $this->sasl_bind($this->prop['auth_cid'], $bind_pass, $bind_user); 
     281            } 
     282            else { 
     283                $this->ready = $this->sasl_bind($bind_user, $bind_pass); 
     284            } 
     285        } 
     286 
     287        return $this->ready; 
    266288    } 
    267289 
Note: See TracChangeset for help on using the changeset viewer.