[ Index ]
 

Code source de DokuWiki 2006-11-06

Accédez au Source d'autres logiciels libresSoutenez Angelica Josefina !

title

Body

[fermer]

/inc/auth/ -> ldap.class.php (source)

   1  <?php
   2  /**
   3   * LDAP authentication backend
   4   *
   5   * @license   GPL 2 (http://www.gnu.org/licenses/gpl.html)
   6   * @author    Andreas Gohr <andi@splitbrain.org>
   7   * @author    Chris Smith <chris@jalakaic.co.uk>
   8   */
   9  
  10  class auth_ldap extends auth_basic {
  11      var $cnf = null;
  12      var $con = null;
  13      var $bound = 0; // 0: anonymous, 1: user, 2: superuser
  14  
  15      /**
  16       * Constructor
  17       */
  18      function auth_ldap(){
  19          global $conf;
  20          $this->cnf = $conf['auth']['ldap'];
  21  
  22          // ldap extension is needed
  23          if(!function_exists('ldap_connect')) {
  24              if ($this->cnf['debug'])
  25                  msg("LDAP err: PHP LDAP extension not found.",-1,__LINE__,__FILE__);
  26              $this->success = false;
  27              return;
  28          }
  29  
  30          if(empty($this->cnf['groupkey'])) $this->cnf['groupkey'] = 'cn';
  31  
  32          // try to connect
  33          if(!$this->_openLDAP()) $this->success = false;
  34  
  35          // auth_ldap currently just handles authentication, so no
  36          // capabilities are set
  37      }
  38  
  39      /**
  40       * Check user+password
  41       *
  42       * Checks if the given user exists and the given
  43       * plaintext password is correct by trying to bind
  44       * to the LDAP server
  45       *
  46       * @author  Andreas Gohr <andi@splitbrain.org>
  47       * @return  bool
  48       */
  49      function checkPass($user,$pass){
  50          // reject empty password
  51          if(empty($pass)) return false;
  52          if(!$this->_openLDAP()) return false;
  53  
  54          // indirect user bind
  55          if($this->cnf['binddn'] && $this->cnf['bindpw']){
  56              // use superuser credentials
  57              if(!@ldap_bind($this->con,$this->cnf['binddn'],$this->cnf['bindpw'])){
  58                  if($this->cnf['debug'])
  59                      msg('LDAP bind as superuser: '.htmlspecialchars(ldap_error($this->con)),0,__LINE__,__FILE__);
  60                  return false;
  61              }
  62              $this->bound = 2;
  63          }else if($this->cnf['binddn'] &&
  64                   $this->cnf['usertree'] &&
  65                   $this->cnf['userfilter']) {
  66              // special bind string
  67              $dn = $this->_makeFilter($this->cnf['binddn'],
  68                                       array('user'=>$user,'server'=>$this->cnf['server']));
  69  
  70          }else if(strpos($this->cnf['usertree'], '%{user}')) {
  71              // direct user bind
  72              $dn = $this->_makeFilter($this->cnf['usertree'],
  73                                       array('user'=>$user,'server'=>$this->cnf['server']));
  74  
  75          }else{
  76              // Anonymous bind
  77              if(!@ldap_bind($this->con)){
  78                  msg("LDAP: can not bind anonymously",-1);
  79                  if($this->cnf['debug'])
  80                      msg('LDAP anonymous bind: '.htmlspecialchars(ldap_error($this->con)),0,__LINE__,__FILE__);
  81                  return false;
  82              }
  83          }
  84  
  85          // Try to bind to with the dn if we have one.
  86          if(!empty($dn)) {
  87              // User/Password bind
  88              if(!@ldap_bind($this->con,$dn,$pass)){
  89                  if($this->cnf['debug']){
  90                      msg("LDAP: bind with $dn failed", -1,__LINE__,__FILE__);
  91                      msg('LDAP user dn bind: '.htmlspecialchars(ldap_error($this->con)),0);
  92                  }
  93                  return false;
  94              }
  95              $this->bound = 1;
  96              return true;
  97          }else{
  98              // See if we can find the user
  99              $info = $this->getUserData($user);
 100              if(empty($info['dn'])) {
 101                  return false;
 102              } else {
 103                  $dn = $info['dn'];
 104              }
 105  
 106              // Try to bind with the dn provided
 107              if(!@ldap_bind($this->con,$dn,$pass)){
 108                  if($this->cnf['debug']){
 109                      msg("LDAP: bind with $dn failed", -1,__LINE__,__FILE__);
 110                      msg('LDAP user bind: '.htmlspecialchars(ldap_error($this->con)),0);
 111                  }
 112                  return false;
 113              }
 114              $this->bound = 1;
 115              return true;
 116          }
 117  
 118          return false;
 119      }
 120  
 121      /**
 122       * Return user info
 123       *
 124       * Returns info about the given user needs to contain
 125       * at least these fields:
 126       *
 127       * name string  full name of the user
 128       * mail string  email addres of the user
 129       * grps array   list of groups the user is in
 130       *
 131       * This LDAP specific function returns the following
 132       * addional fields:
 133       *
 134       * dn   string  distinguished name (DN)
 135       * uid  string  Posix User ID
 136       *
 137       * @author  Andreas Gohr <andi@splitbrain.org>
 138       * @author  Trouble
 139       * @author  Dan Allen <dan.j.allen@gmail.com>
 140       * @auhtor  <evaldas.auryla@pheur.org>
 141       * @return  array containing user data or false
 142       */
 143      function getUserData($user) {
 144          global $conf;
 145          if(!$this->_openLDAP()) return false;
 146  
 147          // force superuser bind if wanted and not bound as superuser yet
 148          if($this->cnf['binddn'] && $this->cnf['bindpw'] && $this->bound < 2){
 149              // use superuser credentials
 150              if(!@ldap_bind($this->con,$this->cnf['binddn'],$this->cnf['bindpw'])){
 151                  if($this->cnf['debug'])
 152                      msg('LDAP bind as superuser: '.htmlspecialchars(ldap_error($this->con)),0,__LINE__,__FILE__);
 153                  return false;
 154              }
 155              $this->bound = 2;
 156          }
 157          // with no superuser creds we continue as user or anonymous here
 158  
 159          $info['user']   = $user;
 160          $info['server'] = $this->cnf['server'];
 161  
 162          //get info for given user
 163          $base = $this->_makeFilter($this->cnf['usertree'], $info);
 164          if(!empty($this->cnf['userfilter'])) {
 165              $filter = $this->_makeFilter($this->cnf['userfilter'], $info);
 166          } else {
 167              $filter = "(ObjectClass=*)";
 168          }
 169  
 170          $sr     = @ldap_search($this->con, $base, $filter);
 171          $result = @ldap_get_entries($this->con, $sr);
 172          if($this->cnf['debug'])
 173              msg('LDAP user search: '.htmlspecialchars(ldap_error($this->con)),0,__LINE__,__FILE__);
 174  
 175          // Don't accept more or less than one response
 176          if($result['count'] != 1){
 177              return false; //user not found
 178          }
 179  
 180          $user_result = $result[0];
 181          ldap_free_result($sr);
 182  
 183          // general user info
 184          $info['dn']   = $user_result['dn'];
 185          $info['mail'] = $user_result['mail'][0];
 186          $info['name'] = $user_result['cn'][0];
 187          $info['grps'] = array();
 188  
 189          // overwrite if other attribs are specified.
 190          if(is_array($this->cnf['mapping'])){
 191              foreach($this->cnf['mapping'] as $localkey => $key) {
 192                  if(is_array($key)) {
 193                      // use regexp to clean up user_result
 194                      list($key, $regexp) = each($key);
 195                      foreach($user_result[$key] as $grp){
 196                          if (preg_match($regexp,$grp,$match)) {
 197                              if($localkey == 'grps') {
 198                                  $info[$localkey][] = $match[1];
 199                              } else {
 200                                  $info[$localkey] = $match[1];
 201                              }
 202                          }
 203                      }
 204                  } else {
 205                      $info[$localkey] = $user_result[$key][0];
 206                  }
 207              }
 208          }
 209          $user_result = array_merge($info,$user_result);
 210  
 211          //get groups for given user if grouptree is given
 212          if ($this->cnf['grouptree'] && $this->cnf['groupfilter']) {
 213              $base   = $this->_makeFilter($this->cnf['grouptree'], $user_result);
 214              $filter = $this->_makeFilter($this->cnf['groupfilter'], $user_result);
 215  
 216              $sr = @ldap_search($this->con, $base, $filter, array($this->cnf['groupkey']));
 217              if(!$sr){
 218                  msg("LDAP: Reading group memberships failed",-1);
 219                  if($this->cnf['debug'])
 220                      msg('LDAP group search: '.htmlspecialchars(ldap_error($this->con)),0,__LINE__,__FILE__);
 221                  return false;
 222              }
 223              $result = ldap_get_entries($this->con, $sr);
 224              ldap_free_result($sr);
 225  
 226              foreach($result as $grp){
 227                  if(!empty($grp[$this->cnf['groupkey']][0])){
 228                      if($this->cnf['debug'])
 229                          msg('LDAP usergroup: '.htmlspecialchars($grp[$this->cnf['groupkey']][0]),0,__LINE__,__FILE__);
 230                      $info['grps'][] = $grp[$this->cnf['groupkey']][0];
 231                  }
 232              }
 233          }
 234  
 235          // always add the default group to the list of groups
 236          if(!in_array($conf['defaultgroup'],$info['grps'])){
 237              $info['grps'][] = $conf['defaultgroup'];
 238          }
 239          return $info;
 240      }
 241  
 242      /**
 243       * Make LDAP filter strings.
 244       *
 245       * Used by auth_getUserData to make the filter
 246       * strings for grouptree and groupfilter
 247       *
 248       * filter      string  ldap search filter with placeholders
 249       * placeholders array   array with the placeholders
 250       *
 251       * @author  Troels Liebe Bentsen <tlb@rapanden.dk>
 252       * @return  string
 253       */
 254      function _makeFilter($filter, $placeholders) {
 255          preg_match_all("/%{([^}]+)/", $filter, $matches, PREG_PATTERN_ORDER);
 256          //replace each match
 257          foreach ($matches[1] as $match) {
 258              //take first element if array
 259              if(is_array($placeholders[$match])) {
 260                  $value = $placeholders[$match][0];
 261              } else {
 262                  $value = $placeholders[$match];
 263              }
 264              $filter = str_replace('%{'.$match.'}', $value, $filter);
 265          }
 266          return $filter;
 267      }
 268  
 269      /**
 270       * Opens a connection to the configured LDAP server and sets the wanted
 271       * option on the connection
 272       *
 273       * @author  Andreas Gohr <andi@splitbrain.org>
 274       */
 275      function _openLDAP(){
 276          if($this->con) return true; // connection already established
 277  
 278          $this->bound = 0;
 279  
 280          $port = ($this->cnf['port']) ? $this->cnf['port'] : 389;
 281          $this->con = @ldap_connect($this->cnf['server'],$port);
 282          if(!$this->con){
 283              msg("LDAP: couldn't connect to LDAP server",-1);
 284              return false;
 285          }
 286  
 287          //set protocol version and dependend options
 288          if($this->cnf['version']){
 289              if(!@ldap_set_option($this->con, LDAP_OPT_PROTOCOL_VERSION,
 290                                   $this->cnf['version'])){
 291                  msg('Setting LDAP Protocol version '.$this->cnf['version'].' failed',-1);
 292                  if($this->cnf['debug'])
 293                      msg('LDAP version set: '.htmlspecialchars(ldap_error($this->con)),0,__LINE__,__FILE__);
 294              }else{
 295                  //use TLS (needs version 3)
 296                  if($this->cnf['starttls']) {
 297                      if (!@ldap_start_tls($this->con)){
 298                          msg('Starting TLS failed',-1);
 299                          if($this->cnf['debug'])
 300                              msg('LDAP TLS set: '.htmlspecialchars(ldap_error($this->con)),0,__LINE__,__FILE__);
 301                      }
 302                  }
 303                  // needs version 3
 304                  if(isset($this->cnf['referrals'])) {
 305                      if(!@ldap_set_option($this->con, LDAP_OPT_REFERRALS,
 306                         $this->cnf['referrals'])){
 307                          msg('Setting LDAP referrals to off failed',-1);
 308                          if($this->cnf['debug'])
 309                              msg('LDAP referal set: '.htmlspecialchars(ldap_error($this->con)),0,__LINE__,__FILE__);
 310                      }
 311                  }
 312              }
 313          }
 314  
 315          //set deref mode
 316          if($this->cnf['deref']){
 317              if(!@ldap_set_option($this->con, LDAP_OPT_DEREF, $this->cnf['deref'])){
 318                  msg('Setting LDAP Deref mode '.$this->cnf['deref'].' failed',-1);
 319                  if($this->cnf['debug'])
 320                      msg('LDAP deref set: '.htmlspecialchars(ldap_error($this->con)),0,__LINE__,__FILE__);
 321              }
 322          }
 323  
 324          return true;
 325      }
 326  }
 327  
 328  //Setup VIM: ex: et ts=4 enc=utf-8 :


Généré le : Tue Apr 3 20:47:31 2007 par Balluche grâce à PHPXref 0.7