fogproject  1.5.9
About: FOG is a Linux-based network computer cloning solution for Windows, Mac OSX and various Linux distributions that ties together a few open-source tools with a PHP-based web interface. FOG doesn’t use any boot disks, or CDs; everything is done via TFTP and PXE.
  Fossies Dox: fogproject-1.5.9.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

ldap.class.php
Go to the documentation of this file.
1 <?php
26 class LDAP extends FOGController
27 {
33  private static $_ldapconn;
39  protected $databaseTable = 'LDAPServers';
45  protected $databaseFields = array(
46  'id' => 'lsID',
47  'name' => 'lsName',
48  'description' => 'lsDesc',
49  'createdBy' => 'lsCreatedBy',
50  'createdTime' => 'lsCreatedTime',
51  'address' => 'lsAddress',
52  'port' => 'lsPort',
53  'searchDN' => 'lsUserSearchDN',
54  'userNamAttr' => 'lsUserNamAttr',
55  'grpMemberAttr' => 'lsGrpMemberAttr',
56  'adminGroup' => 'lsAdminGroup',
57  'userGroup' => 'lsUserGroup',
58  'searchScope' => 'lsSearchScope',
59  'bindDN' => 'lsBindDN',
60  'bindPwd' => 'lsBindPwd',
61  'grpSearchDN' => 'lsGrpSearchDN',
62  'useGroupMatch' => 'lsUseGroupMatch',
63  );
69  protected $databaseFieldsRequired = array(
70  'name',
71  'address',
72  'port',
73  'searchDN',
74  //'userNamAttr',
75  //'grpMemberAttr',
76  'searchScope',
77  'useGroupMatch',
78  // 'grpSearchDN',
86  // 'adminGroup',
87  // 'userGroup',
88  );
99  public function __call($function, $args)
100  {
101  $func = $function;
102  $function = 'ldap_'.$func;
103  if (!function_exists($function)) {
104  throw new Exception(
105  sprintf(
106  '%s %s',
107  _('Function does not exist'),
108  $function
109  )
110  );
111  }
112  $nonresourcefuncs = array(
113  '8859_to_t61',
114  'connect',
115  'dn2ufn',
116  'err2str',
117  'escape',
118  'explode_dn',
119  't61_to_8859',
120  );
121  if (!in_array($func, $nonresourcefuncs)) {
122  array_unshift($args, self::$_ldapconn);
123  }
124  $ret = call_user_func_array($function, $args);
125  return $ret;
126  }
134  private function _ldapUp($timeout = 3)
135  {
136  $ldap = 'ldap';
137  $ports = array_map(
138  'trim',
139  explode(
140  ',',
141  self::getSetting('LDAP_PORTS')
142  )
143  );
144  $port = $this->get('port');
145  $address = preg_replace('#^.*://#i', '', $this->get('address'));
146  if (!in_array($port, $ports)) {
147  throw new Exception(_('Port is not valid ldap/ldaps port'));
148  }
149  $sock = @pfsockopen(
150  $address,
151  $port,
152  $errno,
153  $errstr,
154  $timeout
155  );
156  if ($sock === false) {
157  return false;
158  }
159  fclose($sock);
160  return sprintf(
161  '%s%s://%s',
162  $ldap,
163  (
164  in_array($port, [ 636, 686, 3269, 7636 ]) ?
165  's' :
166  ''
167  ),
168  $address
169  );
170  }
178  private function _ldapParseDn($dn)
179  {
183  $parser = $this->explode_dn($dn, 0);
187  $out = array();
192  foreach ((array)$parser as $key => &$value) {
193  if (false !== strstr($value, '=')) {
194  list(
195  $prefix,
196  $data
197  ) = explode('=', $value);
198  $prefix = strtoupper($prefix);
199  preg_replace_callback(
200  "/\\\‍([0-9A-Fa-f]{2})/",
201  function ($matches) {
202  foreach ((array)$matches as &$match) {
203  return chr(hexdec($match));
204  }
205  },
206  $data
207  );
208  if (isset($current_prefix)
209  && $prefix == $current_prefix
210  ) {
211  $out[$prefix][] = $data;
212  } else {
213  $current_prefix = $prefix;
214  $out[$prefix][] = $data;
215  }
216  }
217  unset($value);
218  }
219  return $out;
220  }
229  public function authLDAP($user, $pass)
230  {
234  @$this->unbind();
239  $user = trim($user);
240  $pass = trim($pass);
246  if (empty($user)
247  || empty($pass)
248  ) {
249  return false;
250  }
256  if (!$server = $this->_ldapUp()) {
257  return false;
258  }
263  $test = preg_match(
264  '/(?=^.{3,40}$)^[\w][\w0-9]*[._-]?[\w0-9]*[.]?[\w0-9]+$/i',
265  $user
266  );
267  if (!$test) {
268  return false;
269  }
275  if (empty($user)) {
276  return false;
277  }
278  $port = (int)$this->get('port');
282  self::$_ldapconn = ldap_connect(
283  $server,
284  $port
285  );
289  if (!self::$_ldapconn) {
290  error_log(
291  sprintf(
292  '%s %s() %s %s:%d',
293  _('Plugin'),
294  __METHOD__,
295  _('We cannot connect to LDAP server'),
296  $server,
297  $port
298  )
299  );
300  return false;
301  }
305  $this->set_option(
306  LDAP_OPT_PROTOCOL_VERSION,
307  3
308  );
309  $this->set_option(
310  LDAP_OPT_REFERRALS,
311  0
312  );
319  $accessLevel = 0;
323  $useGroupMatch = $this->get('useGroupMatch');
327  $bindDN = $this->get('bindDN');
331  $bindPass = $this->get('bindPwd');
335  $usrNamAttr = strtolower($this->get('userNamAttr'));
339  $grpMemAttr = strtolower($this->get('grpMemberAttr'));
343  $searchDN = $this->get('searchDN');
347  $parsedDN = $this->_ldapParseDn($searchDN);
354  if ($useGroupMatch > 0 && !empty($bindDN)) {
358  $bindPass = trim($bindPass);
362  $bindPasstest = self::aesdecrypt($bindPass);
363  if ($test_base64 = base64_decode($bindPasstest)) {
364  if (mb_detect_encoding($test_base64, 'utf-8', true)) {
365  $bindPass = $test_base64;
366  } elseif (mb_detect_encoding($bindPasstest, 'utf-8', true)) {
367  $bindPass = $bindPasstest;
368  }
369  }
373  if (empty($bindPass)) {
374  error_log(
375  sprintf(
376  '%s %s() %s %s!',
377  _('Plugin'),
378  __METHOD__,
379  _('Using the group match function'),
380  _('but bind password is not set')
381  )
382  );
383  return false;
384  }
388  $bind = @$this->bind($bindDN, $bindPass);
392  if (!$bind) {
393  error_log(
394  sprintf(
395  '%s %s() %s %s:%d',
396  _('Plugin'),
397  __METHOD__,
398  _('Cannot bind to the LDAP server'),
399  $server,
400  $port
401  )
402  );
403  return false;
404  }
408  $filter = sprintf(
409  '(&(|(objectcategory=person)(objectclass=person))(%s=%s))',
410  $usrNamAttr,
411  $user
412  );
416  $attr = array('dn');
420  $result = $this->_result($searchDN, $filter, $attr);
424  if ($result === false) {
425  error_log(
426  sprintf(
427  '%s %s() %s. %s: %s; %s: %s',
428  _('Plugin'),
429  __METHOD__,
430  _('Search results returned false'),
431  _('Search DN'),
432  $searchDN,
433  _('Filter'),
434  $filter
435  )
436  );
437  return false;
438  }
442  $entries = $this->get_entries($result);
446  $userDN = $entries[0]['dn'];
450  $bind = @$this->bind($userDN, $pass);
454  if (!$bind) {
455  error_log(
456  sprintf(
457  '%s %s() %s. %s: %s',
458  _('Plugin'),
459  __METHOD__,
460  _('User was not authorized by the LDAP server'),
461  _('User DN'),
462  $userDN
463  )
464  );
465  return false;
466  }
467  } else {
471  $parsedDN = $this->_ldapParseDn($searchDN);
475  $userDomain = implode('.', (array)$parsedDN['DC']);
479  $userDN = sprintf(
480  '%s=%s,%s',
481  $usrNamAttr,
482  $user,
483  $searchDN
484  );
485  $userDN1 = sprintf(
486  '%s@%s',
487  $user,
488  $userDomain
489  );
490  $userDN2 = sprintf(
491  '%s\%s',
492  $userDomain,
493  $user
494  );
498  if (!@$this->bind($userDN, $pass)) {
499  $userDN = $userDN1;
500  }
501  if (!@$this->bind($userDN, $pass)) {
502  $userDN = $userDN2;
503  }
504  if (!@$this->bind($userDN, $pass)) {
505  error_log(
506  sprintf(
507  '%s %s() %s.',
508  _('Plugin'),
509  __METHOD__,
510  _('All methods of binding have failed')
511  )
512  );
513  @$this->unbind();
514  return false;
515  }
516  }
517  $attr = array('dn');
518  $filter = sprintf(
519  '(&(|(objectcategory=person)(objectclass=person))(%s=%s))',
520  $usrNamAttr,
521  $user
522  );
523  $result = $this->_result($searchDN, $filter, $attr);
524  if (false === $result) {
525  error_log(
526  sprintf(
527  '%s %s() %s. %s: %s; %s: %s',
528  _('Plugin'),
529  __METHOD__,
530  _('Search DN did not return any results'),
531  _('Search DN'),
532  $searchDN,
533  _('Filter'),
534  $filter
535  )
536  );
537  @$this->unbind();
538  return false;
539  }
543  $entries = $this->get_entries($result);
547  $userDN = $entries[0]['dn'];
553  if ($useGroupMatch) {
554  $accessLevel = $this->_getAccessLevel($grpMemAttr, $userDN);
555  } else {
556  $accessLevel = 2;
557  }
561  @$this->unbind();
567  if ($accessLevel == 0) {
568  error_log(
569  sprintf(
570  '%s %s() %s. %s!',
571  _('Plugin'),
572  __METHOD__,
573  _('Access level is still 0 or false'),
574  _('No access is allowed')
575  )
576  );
577  return false;
578  }
584  return $accessLevel;
585  }
594  private function _getAccessLevel($grpMemAttr, $userDN)
595  {
599  $accessLevel = false;
603  $adminGroup = $this->get('adminGroup');
607  $userGroup = $this->get('userGroup');
611  $grpSearchDN = $this->get('grpSearchDN');
612  if (!$grpSearchDN) {
613  $parsedDN = $this->_ldapParseDn($userDN);
614  $grpSearchDN = 'dc='.implode(',dc=', $parsedDN['DC']);
615  }
619  $adminGroups = explode(',', $adminGroup);
620  $adminGroups = array_map('trim', $adminGroups);
621  $filter = sprintf(
622  '(&(|(name=%s))(%s=%s))',
623  implode(')(name=', (array)$adminGroups),
624  $grpMemAttr,
625  $this->escape($userDN, null, LDAP_ESCAPE_FILTER)
626  );
630  $attr = array($grpMemAttr);
634  $result = $this->_result($grpSearchDN, $filter, $attr);
635  if (false !== $result) {
636  return 2;
637  }
643  $userGroups = explode(',', $userGroup);
644  $userGroups = array_map('trim', $userGroups);
645  $filter = sprintf(
646  '(&(|(name=%s))(%s=%s))',
647  implode(')(name=', (array)$userGroups),
648  $grpMemAttr,
649  $this->escape($userDN, null, LDAP_ESCAPE_FILTER)
650  );
654  $attr = array($grpMemAttr);
658  $result = $this->_result($grpSearchDN, $filter, $attr);
662  if (false !== $result) {
663  return 1;
664  }
668  $filter = sprintf(
669  '(%s=*)',
670  $grpMemAttr
671  );
675  $attr = array($grpMemAttr);
679  $result = $this->_result($grpSearchDN, $filter, $attr);
683  if (false === $result) {
684  error_log(
685  sprintf(
686  '%s %s() %s. %s: %s',
687  _('Plugin'),
688  __METHOD__,
689  _('Group Search DN did not return any results'),
690  _('Group Search DN'),
691  $grpSearchDN
692  )
693  );
694  @$this->unbind();
695  return false;
696  }
700  $entries = $this->get_entries($result);
704  $pat = sprintf(
705  '#%s#i',
706  $userDN
707  );
711  foreach ((array)$entries as &$entry) {
715  if (!isset($entry['dn'])) {
716  continue;
717  }
721  $dn = $entry['dn'];
725  $users = $entry[$grpMemAttr];
729  $admin = false;
730  if ($adminGroup) {
731  $admin = strpos($dn, $adminGroup);
732  }
736  $user = false;
737  if ($userGroup) {
738  $user = strpos($dn, $userGroup);
739  }
744  if (false === $admin
745  && false === $user
746  ) {
747  continue;
748  }
752  if (false !== $admin) {
756  $adm = preg_grep($pat, $users);
760  $adm = array_filter($adm);
764  if (count($adm) > 0) {
765  $accessLevel = 2;
766  break;
767  }
768  }
772  if (false !== $user) {
776  $usr = preg_grep($pat, $users);
780  $usr = array_filter($usr);
786  if (count($usr) > 0) {
787  $accessLevel = 1;
788  }
789  }
790  }
794  return $accessLevel;
795  }
805  private function _result($searchDN, $filter, array $attr)
806  {
813  $searchScope = (int)$this->get('searchScope');
817  switch ($searchScope) {
818  case 1:
819  $method = 'list';
820  break;
821  case 2:
822  $method = 'search';
823  break;
824  default:
825  $method = 'read';
826  }
830  $searchDN = mb_convert_encoding($searchDN, 'utf-8');
834  $result = $this->{$method}($searchDN, $filter, $attr);
838  $retcount = $this->count_entries($result);
842  if ($retcount < 1) {
843  error_log(
844  sprintf(
845  '%s %s(). %s: %s; %s: %s; %s: %s',
846  _('Plugin'),
847  __METHOD__,
848  _('Search Method'),
849  $method,
850  _('Filter'),
851  $filter,
852  _('Result'),
853  $retcount
854  )
855  );
856  return false;
857  }
861  return $result;
862  }
870  public function get($key = '')
871  {
872  $keys = array(
873  'searchDN',
874  'grpSearchDN',
875  'bindDN',
876  'adminGroup',
877  'userGroup'
878  );
879  if (in_array($key, $keys)) {
880  $dn = trim(parent::get($key));
881  $dn = strtolower($dn);
882  $dn = html_entity_decode(
883  $dn,
884  ENT_QUOTES,
885  'utf-8'
886  );
887  $dn = mb_convert_case(
888  $dn,
889  MB_CASE_LOWER,
890  'utf-8'
891  );
892  $this->set($key, $dn);
893  }
894  return parent::get($key);
895  }
896 }
LDAP
Definition: ldap.class.php:27
LDAP\$databaseTable
$databaseTable
Definition: ldap.class.php:39
LDAP\$databaseFieldsRequired
$databaseFieldsRequired
Definition: ldap.class.php:69
$test
$test
Definition: freespace.php:37
LDAP\_result
_result($searchDN, $filter, array $attr)
Definition: ldap.class.php:805
$user
$user
Definition: advanced.php:38
LDAP\_ldapParseDn
_ldapParseDn($dn)
Definition: ldap.class.php:178
LDAP\_getAccessLevel
_getAccessLevel($grpMemAttr, $userDN)
Definition: ldap.class.php:594
$keys
$keys
Definition: schema.php:1610
LDAP\__call
__call($function, $args)
Definition: ldap.class.php:99
$ret
$ret
Definition: bandwidth.php:112
FOGBase\aesdecrypt
static aesdecrypt( $encdata, $key=false, $enctype='aes-128-cbc')
Definition: fogbase.class.php:1536
FOGController
Definition: fogcontroller.class.php:29
FOGController\$data
$data
Definition: fogcontroller.class.php:35
LDAP\$_ldapconn
static $_ldapconn
Definition: ldap.class.php:33
LDAP\$databaseFields
$databaseFields
Definition: ldap.class.php:45
LDAP\authLDAP
authLDAP($user, $pass)
Definition: ldap.class.php:229
LDAP\_ldapUp
_ldapUp($timeout=3)
Definition: ldap.class.php:134
$pass
$pass
Definition: hostinfo.php:161