FusionDirectory
 All Data Structures Files Functions Variables
class_config.inc
Go to the documentation of this file.
1 <?php
2 /*
3  This code is part of FusionDirectory (http://www.fusiondirectory.org/)
4  Copyright (C) 2003-2010 Cajus Pollmeier
5  Copyright (C) 2011-2017 FusionDirectory
6 
7  This program is free software; you can redistribute it and/or modify
8  it under the terms of the GNU General Public License as published by
9  the Free Software Foundation; either version 2 of the License, or
10  (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
20 */
21 
31 class config
32 {
33  /* XML parser */
34  var $parser;
35  var $config_found = FALSE;
36  var $tags = array();
37  var $level = 0;
38  var $gpc = 0;
39  var $section = '';
40  var $currentLocation = '';
41 
45  var $current = array();
46 
47  /* Link to LDAP-server */
48  var $ldap = NULL;
49  var $referrals = array();
50 
51  /*
52  * \brief Configuration data
53  *
54  * - $data['SERVERS'] contains server informations.
55  */
56  var $data = array(
57  'LOCATIONS' => array(),
58  'SERVERS' => array(),
59  'MAIN' => array(),
60  );
61  var $basedir = '';
62 
63  /* Keep a copy of the current department list */
64  var $departments = array();
65  var $idepartments = array();
66  var $department_info = array();
67  var $filename = '';
68  var $last_modified = 0;
69 
77  function __construct($filename, $basedir = '')
78  {
79  $this->basedir = $basedir;
80 
81  /* Parse config file directly? */
82  if ($filename != '') {
83  $this->parse($filename);
84  }
85  }
86 
94  function check_and_reload($force = FALSE)
95  {
96  /* Check if class_location.inc has changed, this is the case
97  if we have installed or removed plugins. */
98  $tmp = stat(CACHE_DIR.'/'.CLASS_CACHE);
99  if (session::global_is_set('class_location.inc:timestamp')) {
100  if ($tmp['mtime'] != session::global_get('class_location.inc:timestamp')) {
101  session::global_un_set('plist');
102  }
103  }
104  session::global_set('class_location.inc:timestamp', $tmp['mtime']);
105 
106  if (($this->filename != '') && ((filemtime($this->filename) != $this->last_modified) || $force)) {
107 
108  $this->config_found = FALSE;
109  $this->tags = array();
110  $this->level = 0;
111  $this->gpc = 0;
112  $this->section = '';
113  $this->currentLocation = '';
114 
115  $this->parse($this->filename);
116  $this->set_current($this->current['NAME']);
117  }
118  }
119 
128  function parse($filename)
129  {
130  $this->last_modified = filemtime($filename);
131  $this->filename = $filename;
132  $fh = fopen($filename, 'r');
133  $xmldata = fread($fh, 100000);
134  fclose($fh);
135  $this->parse_data($xmldata);
136  }
137 
138  function parse_data ($xmldata)
139  {
140  $this->data = array(
141  'LOCATIONS' => array(),
142  'SERVERS' => array(),
143  'MAIN' => array(),
144  );
145 
146  $this->parser = xml_parser_create();
147  xml_set_object($this->parser, $this);
148  xml_set_element_handler($this->parser, "tag_open", "tag_close");
149 
150  if (!xml_parse($this->parser, chop($xmldata))) {
151  $msg = sprintf(_("XML error in fusiondirectory.conf: %s at line %d"),
152  xml_error_string(xml_get_error_code($this->parser)),
153  xml_get_current_line_number($this->parser));
154  msg_dialog::display(_("Configuration error"), $msg, FATAL_ERROR_DIALOG);
155  exit;
156  }
157  xml_parser_free($this->parser);
158  }
159 
169  function tag_open($parser, $tag, $attrs)
170  {
171  /* Save last and current tag for reference */
172  $this->tags[$this->level] = $tag;
173  $this->level++;
174 
175  /* Trigger on CONF section */
176  if ($tag == 'CONF') {
177  $this->config_found = TRUE;
178  }
179 
180  /* Return if we're not in config section */
181  if (!$this->config_found) {
182  return;
183  }
184 
185  /* yes/no to true/false and upper case TRUE to true and so on*/
186  foreach ($attrs as $name => $value) {
187  if (preg_match("/^(true|yes)$/i", $value)) {
188  $attrs[$name] = "TRUE";
189  } elseif (preg_match("/^(false|no)$/i", $value)) {
190  $attrs[$name] = "FALSE";
191  }
192  }
193 
194  /* Look through attributes */
195  switch ($this->tags[$this->level - 1]) {
196  /* Handle location */
197  case 'LOCATION':
198  if ($this->tags[$this->level - 2] == 'MAIN') {
199  $attrs['NAME'] = preg_replace('/[<>"\']/', '', $attrs['NAME']);
200 
201  $this->currentLocation = $attrs['NAME'];
202 
203  /* Add location elements */
204  $this->data['LOCATIONS'][$attrs['NAME']] = $attrs;
205  }
206  break;
207 
208  /* Handle referral tags */
209  case 'REFERRAL':
210  if ($this->tags[$this->level - 2] == 'LOCATION') {
211  $server = preg_replace('!^([^:]+://[^/]+)/.*$!', '\\1', $attrs['URI']);
212 
213  /* Add location elements */
214  if (!isset($this->data['LOCATIONS'][$this->currentLocation]['REFERRAL'])) {
215  $this->data['LOCATIONS'][$this->currentLocation]['REFERRAL'] = array();
216  }
217 
218  $this->data['LOCATIONS'][$this->currentLocation]['REFERRAL'][$server] = $attrs;
219  }
220  break;
221 
222  /* Load main parameters */
223  case 'MAIN':
224  $this->data['MAIN'] = array_merge ($this->data['MAIN'], $attrs);
225  break;
226 
227  /* Ignore other tags */
228  default:
229  break;
230  }
231  }
232 
240  function tag_close($parser, $tag)
241  {
242  /* Close config section */
243  if ($tag == 'CONF') {
244  $this->config_found = FALSE;
245  }
246  $this->level--;
247  }
248 
259  function get_credentials($creds)
260  {
261  if (isset($_SERVER['HTTP_FDKEY'])) {
262  if (!session::global_is_set('HTTP_FDKEY_CACHE')) {
263  session::global_set('HTTP_FDKEY_CACHE', array());
264  }
265  $cache = session::global_get('HTTP_FDKEY_CACHE');
266  if (!isset($cache[$creds])) {
267  try {
268  $cache[$creds] = cred_decrypt($creds, $_SERVER['HTTP_FDKEY']);
269  session::global_set('HTTP_FDKEY_CACHE', $cache);
270  } catch (FusionDirectoryException $e) {
271  $msg = sprintf(
272  _('It seems you are trying to decode something which is not encoded : %s<br/>'."\n".
273  'Please check you are not using a fusiondirectory.secrets file while your passwords are not encrypted.'),
274  $e->getMessage()
275  );
276  msg_dialog::display(_('Configuration error'), $msg, FATAL_ERROR_DIALOG);
277  exit;
278  }
279  }
280  return $cache[$creds];
281  }
282  return $creds;
283  }
284 
303  function get_ldap_link($sizelimit = FALSE)
304  {
305  if ($this->ldap === NULL || !is_resource($this->ldap->cid)) {
306 
307  /* Build new connection */
308  $this->ldap = ldap_init ($this->current['SERVER'], $this->current['BASE'],
309  $this->current['ADMINDN'], $this->get_credentials($this->current['ADMINPASSWORD']));
310 
311  /* Check for connection */
312  if (is_null($this->ldap) || (is_int($this->ldap) && $this->ldap == 0)) {
313  msg_dialog::display(_("LDAP error"), _("Cannot bind to LDAP. Please contact the system administrator."), FATAL_ERROR_DIALOG);
314  exit();
315  }
316 
317  /* Move referrals */
318  if (!isset($this->current['REFERRAL'])) {
319  $this->ldap->referrals = array();
320  } else {
321  $this->ldap->referrals = $this->current['REFERRAL'];
322  }
323 
324  if (!session::global_is_set('size_limit')) {
325  session::global_set('size_limit', $this->current['LDAPSIZELIMIT']);
326  session::global_set('size_ignore', preg_match('/true/i', $this->current['LDAPSIZEIGNORE']));
327  }
328  }
329 
330  $obj = new ldapMultiplexer($this->ldap);
331  if ($sizelimit) {
332  $obj->set_size_limit(session::global_get('size_limit'));
333  } else {
334  $obj->set_size_limit(0);
335  }
336  return $obj;
337  }
338 
344  function set_current($name)
345  {
346  if (!isset($this->data['LOCATIONS'][$name])) {
347  msg_dialog::display(_('Error'), sprintf(_('Location "%s" could not be found in the configuration file'), $name), FATAL_ERROR_DIALOG);
348  exit;
349  }
350  $this->current = $this->data['LOCATIONS'][$name];
351 
352  if (isset($this->current['INITIAL_BASE'])) {
353  session::global_set('CurrentMainBase', $this->current['INITIAL_BASE']);
354  }
355 
356  /* Sort referrals, if present */
357  if (isset($this->current['REFERRAL'])) {
358  $bases = array();
359  $servers = array();
360  foreach ($this->current['REFERRAL'] as $ref) {
361  $server = preg_replace('%^(.*://[^/]+)/.*$%', '\\1', $ref['URI']);
362  $base = preg_replace('%^.*://[^/]+/(.*)$%', '\\1', $ref['URI']);
363 
364  $bases[$base] = strlen($base);
365  $servers[$base] = $server;
366  }
367  asort($bases);
368  reset($bases);
369  }
370 
371  /* SERVER not defined? Load the one with the shortest base */
372  if (!isset($this->current['SERVER'])) {
373  $this->current['SERVER'] = $servers[key($bases)];
374  }
375 
376  /* BASE not defined? Load the one with the shortest base */
377  if (!isset($this->current['BASE'])) {
378  $this->current['BASE'] = key($bases);
379  }
380 
381  /* Parse LDAP referral informations */
382  if (!isset($this->current['ADMINDN']) || !isset($this->current['ADMINPASSWORD'])) {
383  $url = $this->current['SERVER'];
384  $referral = $this->current['REFERRAL'][$url];
385 
386  $this->current['ADMINDN'] = $referral['ADMINDN'];
387  $this->current['ADMINPASSWORD'] = $referral['ADMINPASSWORD'];
388  }
389 
390  /* We need LDAPSIZELIMIT and LDAPSIZEIGNORE set before we connect to the ldap */
391  if (!isset($this->current['LDAPSIZELIMIT'])) {
392  $this->current['LDAPSIZELIMIT'] = 200;
393  }
394  if (!isset($this->current['LDAPSIZEIGNORE'])) {
395  $this->current['LDAPSIZEIGNORE'] = "TRUE";
396  }
397 
398  /* Load in-ldap configuration */
399  $this->load_inldap_config();
400 
401  /* We update LDAPSIZELIMIT as it may have been changed by ldap config */
402  session::global_set('size_limit', $this->current['LDAPSIZELIMIT']);
403 
404  if (class_available('systemManagement')) {
405  /* Load server informations */
406  $this->load_servers();
407  }
408 
409  $debugLevel = $this->get_cfg_value('DEBUGLEVEL');
410  if ($debugLevel & DEBUG_CONFIG) {
411  /* Value from LDAP can't activate DEBUG_CONFIG */
412  $debugLevel -= DEBUG_CONFIG;
413  }
414  if (isset($this->data['MAIN']['DEBUGLEVEL'])) {
415  $debugLevel |= $this->data['MAIN']['DEBUGLEVEL'];
416  }
417  session::global_set('DEBUGLEVEL', $debugLevel);
418 
419  IconTheme::loadThemes('themes');
420 
421  timezone::setDefaultTimezoneFromConfig();
422 
423  initLanguage();
424  }
425 
433  function load_servers ()
434  {
435  /* Only perform actions if current is set */
436  if ($this->current === NULL) {
437  return;
438  }
439 
440  $ldap = $this->get_ldap_link();
441 
442  /* Get samba servers from LDAP */
443  $this->data['SERVERS']['SAMBA'] = array();
444  if (class_available('sambaAccount')) {
445  $ldap->cd($this->current['BASE']);
446  $ldap->search('(objectClass=sambaDomain)');
447  while ($attrs = $ldap->fetch()) {
448  $this->data['SERVERS']['SAMBA'][$attrs['sambaDomainName'][0]] = array( 'SID' => '','RIDBASE' => '');
449  if (isset($attrs['sambaSID'][0])) {
450  $this->data['SERVERS']['SAMBA'][$attrs['sambaDomainName'][0]]['SID'] = $attrs['sambaSID'][0];
451  }
452  if (isset($attrs['sambaAlgorithmicRidBase'][0])) {
453  $this->data['SERVERS']['SAMBA'][$attrs['sambaDomainName'][0]]['RIDBASE'] = $attrs['sambaAlgorithmicRidBase'][0];
454  }
455  }
456 
457  /* If no samba servers are found, look for configured sid/ridbase */
458  if (count($this->data['SERVERS']['SAMBA']) == 0) {
459  if (isset($this->current['SAMBASID']) && isset($this->current['SAMBARIDBASE'])) {
460  $this->data['SERVERS']['SAMBA']['DEFAULT'] = array(
461  'SID' => $this->get_cfg_value('SAMBASID'),
462  'RIDBASE' => $this->get_cfg_value('SAMBARIDBASE')
463  );
464  }
465  }
466  }
467 
468  }
469 
470  /* Check that configuration is in LDAP, check that no plugin got installed since last configuration update */
471  function checkLdapConfig ($forceReload = FALSE)
472  {
473  global $ui;
474  $dn = CONFIGRDN.$this->current['BASE'];
475 
476  if (!$forceReload) {
477  $ldap = $this->get_ldap_link();
478  $ldap->cat($dn, array('fusionConfigMd5'));
479  if ($attrs = $ldap->fetch()) {
480  if (isset($attrs['fusionConfigMd5'][0]) && ($attrs['fusionConfigMd5'][0] == md5_file(CACHE_DIR.'/'.CLASS_CACHE))) {
481  return;
482  }
483  }
484  }
485 
486  add_lock($dn, $ui->dn);
487  $config_plugin = objects::open($dn, 'configuration');
488  $config_plugin->save_object();
489  $config_plugin->save();
490  del_lock($dn);
491  }
492 
493  function load_inldap_config()
494  {
495  $ldap = $this->get_ldap_link();
496  $ldap->cat(CONFIGRDN.$this->current['BASE']);
497  if ($attrs = $ldap->fetch()) {
498  for ($i = 0; $i < $attrs['count']; $i++) {
499  $key = $attrs[$i];
500  if (preg_match('/^fdTabHook$/i', $key)) {
501  for ($j = 0; $j < $attrs[$key]['count']; ++$j) {
502  $parts = explode('|', $attrs[$key][$j], 3);
503  $class = strtoupper($parts[0]);
504  $mode = strtoupper($parts[1]);
505  $cmd = $parts[2];
506  if (!isset($this->data['HOOKS'][$class])) {
507  $this->data['HOOKS'][$class] = array('CLASS' => $parts[0]);
508  }
509  if (!isset($this->data['HOOKS'][$class][$mode])) {
510  $this->data['HOOKS'][$class][$mode] = array();
511  }
512  $this->data['HOOKS'][$class][$mode][] = $cmd;
513  }
514  } elseif (preg_match('/^fd/', $key)) {
515  if (isset($attrs[$key]['count']) && ($attrs[$key]['count'] > 1)) {
516  $value = $attrs[$key];
517  unset($value['count']);
518  } else {
519  $value = $attrs[$key][0];
520  }
521  $key = strtoupper(preg_replace('/^fd/', '', $key));
522  $this->current[$key] = $value;
523  }
524  }
525  }
526  }
527 
531  function get_departments()
532  {
533  /* Initialize result hash */
534  $result = array();
535 
536  $result['/'] = $this->current['BASE'];
537 
538  /* Get all department types from department Management, to be able detect the department type.
539  -It is possible that different department types have the same name,
540  in this case we have to mark the department name to be able to differentiate.
541  (e.g l=Name or o=Name)
542  */
543  $types = departmentManagement::getDepartmentTypes();
544 
545  /* Create a list of attributes to fetch */
546  $filter = '';
547  $ldap_values = array('objectClass', 'description');
548  foreach ($types as $type) {
549  $i = objects::infos($type);
550  $filter .= $i['filter'];
551  /* Add type main attr to fetched attributes list */
552  $ldap_values[] = $i['mainAttr'];
553  }
554  $filter = '(|'.$filter.')';
555 
556  /* Get list of department objects */
557  $ldap = $this->get_ldap_link();
558  $ldap->cd ($this->current['BASE']);
559  $ldap->search ($filter, $ldap_values);
560  while ($attrs = $ldap->fetch()) {
561 
562  /* Detect department type */
563  $oc = NULL;
564  foreach ($types as $type) {
565  if (objects::isOfType($attrs, $type)) {
566  $oc = $type;
567  break;
568  }
569  }
570 
571  /* Unknown department type -> skip */
572  if ($oc == NULL) {
573  continue;
574  }
575 
576  $dn = $attrs['dn'];
577  $data = objects::infos($oc);
578  $this->department_info[$dn] = array(
579  'img' => $data['icon'],
580  'description' => (isset($attrs['description'][0]) ? $attrs['description'][0] : ''),
581  'name' => $attrs[$data['mainAttr']][0]
582  );
583 
584  /* Only assign non-root departments */
585  if ($dn != $result['/']) {
586  $c_dn = convert_department_dn($dn).' ('.$data['mainAttr'].')';
587  $result[$c_dn] = $dn;
588  }
589  }
590 
591  $this->departments = $result;
592  }
593 
594  function make_idepartments($max_size = 28)
595  {
596  $base = $this->current['BASE'];
597  $qbase = preg_quote($base, '/');
598 
599  $arr = array();
600 
601  $this->idepartments = array();
602 
603  /* Create multidimensional array, with all departments. */
604  foreach ($this->departments as $key => $val) {
605 
606  /* Split dn into single department pieces */
607  $elements = array_reverse(explode(',', preg_replace("/$qbase$/", '', $val)));
608 
609  /* Add last ou element of current dn to our array */
610  $last = &$arr;
611  foreach ($elements as $key => $ele) {
612  /* skip empty */
613  if (empty($ele)) {
614  continue;
615  }
616 
617  /* Extract department name */
618  $elestr = trim(preg_replace('/^[^=]*+=/', '', $ele), ',');
619  $nameA = trim(preg_replace('/=.*$/', '', $ele), ',');
620  if ($nameA != 'ou') {
621  $nameA = " ($nameA)";
622  } else {
623  $nameA = '';
624  }
625 
626  /* Add to array */
627  if ($key == (count($elements) - 1)) {
628  $last[$elestr.$nameA]['ENTRY'] = $val;
629  }
630 
631  /* Set next array appending position */
632  $last = &$last[$elestr.$nameA]['SUB'];
633  }
634  }
635 
636  /* Add base entry */
637  $ret['/']['ENTRY'] = $base;
638  $ret['/']['SUB'] = $arr;
639  $this->idepartments = $this->generateDepartmentArray($ret, -1, $max_size);
640  }
641 
642  /*
643  * \brief Creates display friendly output from make_idepartments
644  *
645  * \param $arr arr
646  *
647  * \param int $depth initialized at -1
648  *
649  * \param int $max_size initialized at 256
650  */
651  function generateDepartmentArray($arr, $depth = -1, $max_size = 256)
652  {
653  $ret = array();
654  $depth++;
655 
656  /* Walk through array */
657  ksort($arr);
658  foreach ($arr as $name => $entries) {
659 
660  /* If this department is the last in the current tree position
661  * remove it, to avoid generating output for it */
662  if (count($entries['SUB']) == 0) {
663  unset($entries['SUB']);
664  }
665 
666  /* Fix name, if it contains a replace tag */
667  $name = preg_replace('/\\\\,/', ',', $name);
668 
669  /* Check if current name is too long, then cut it */
670  if (mb_strlen($name, 'UTF-8') > $max_size) {
671  $name = mb_substr($name, 0, ($max_size - 3), 'UTF-8')." ...";
672  }
673 
674  /* Append the name to the list */
675  if (isset($entries['ENTRY'])) {
676  $a = "";
677  for ($i = 0; $i < $depth; $i++) {
678  $a .= ".";
679  }
680  $ret[$entries['ENTRY']] = $a."&nbsp;".$name;
681  }
682 
683  /* recursive add of subdepartments */
684  if (isset($entries['SUB'])) {
685  $ret = array_merge($ret, $this->generateDepartmentArray($entries['SUB'], $depth, $max_size));
686  }
687  }
688 
689  return $ret;
690  }
691 
706  function searchHooks($class, $value)
707  {
708  $class = strtoupper($class);
709  $value = strtoupper($value);
710  return (isset($this->data['HOOKS'][$class][$value]) ? $this->data['HOOKS'][$class][$value] : array());
711  }
712 
730  function get_cfg_value($name, $default = '')
731  {
732  $name = strtoupper($name);
733  $res = $default;
734 
735  /* Check if we have a current value for $name */
736  if (isset($this->current[$name])) {
737  $res = $this->current[$name];
738  } elseif (isset($this->data['MAIN'][$name])) {
739  /* Check if we have a global value for $name */
740  $res = $this->data['MAIN'][$name];
741  }
742 
743  if (is_array($default) && !is_array($res)) {
744  $res = array($res);
745  }
746 
747  return $res;
748  }
749 
764  {
765  $cfg_lifetime = $this->get_cfg_value('SESSIONLIFETIME', 0);
766  if ($cfg_lifetime > 0) {
767  $ini_lifetime = ini_get('session.gc_maxlifetime');
768  $deb_system = file_exists('/etc/debian_version');
769  return !($deb_system && ($ini_lifetime < $cfg_lifetime));
770  } else {
771  return TRUE;
772  }
773  }
774 
780  function snapshotEnabled()
781  {
782  if ($this->get_cfg_value('enableSnapshots') != 'TRUE') {
783  return FALSE;
784  }
785 
786  /* Check if the snapshot_base is defined */
787  if ($this->get_cfg_value('snapshotBase') == '') {
788  /* Send message if not done already */
789  if (!session::is_set('snapshotFailMessageSend')) {
790  session::set('snapshotFailMessageSend', TRUE);
791  msg_dialog::display(_('Configuration error'),
792  sprintf(_('The snapshot functionality is enabled, but the required variable "%s" is not set.'),
793  'snapshotBase'), ERROR_DIALOG);
794  }
795  return FALSE;
796  }
797 
798  /* Check if gzcompress is available */
799  if (!is_callable('gzcompress')) {
800  /* Send message if not done already */
801  if (!session::is_set('snapshotFailMessageSend')) {
802  session::set('snapshotFailMessageSend', TRUE);
803  msg_dialog::display(_('Configuration error'),
804  sprintf(_('The snapshot functionality is enabled, but the required compression module is missing. Please install "%s".'), 'php5-zip / php5-gzip'), ERROR_DIALOG);
805  }
806  return FALSE;
807  }
808  return TRUE;
809  }
810 
811  function loadPlist (pluglist $plist)
812  {
813  $this->data['OBJECTS'] = array();
814  $this->data['SECTIONS'] = array();
815  $this->data['CATEGORIES'] = array();
816  $this->data['MENU'] = array();
817  $this->data['TABS'] = array();
818  foreach ($plist->info as $class => &$plInfo) {
819  if (isset($plInfo['plObjectType'])) {
820  $entry = array('CLASS' => $class,'NAME' => $plInfo['plShortName']);
821  foreach ($plInfo['plObjectType'] as $key => $value) {
822  if (is_numeric($key)) {
823  /* This is not the main tab */
824  $tabclass = strtoupper($value)."TABS";
825  if (($tabclass == 'GROUPTABS') && class_available('mixedGroup')) {
826  $tabclass = 'OGROUP-USERTABS';
827  }
828  @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__, $tabclass, "Adding $class to tab list");
829  if (!isset($this->data['TABS'][$tabclass])) {
830  $this->data['TABS'][$tabclass] = array();
831  }
832  $this->data['TABS'][$tabclass][] = $entry;
833  } else {
834  /* This is the main tab */
835  if (isset($this->data['OBJECTS'][strtoupper($key)])) {
836  die("duplicated object type ".strtoupper($key)." in ".$this->data['OBJECTS'][strtoupper($key)]['mainTab']." and $class");
837  }
838  $tabclass = strtoupper($key)."TABS";
839  $value['tabGroup'] = $tabclass;
840  $value['mainTab'] = $class;
841  $value['templateActive'] = FALSE;
842  foreach (array('ou', 'tabClass') as $i) {
843  if (!isset($value[$i])) {
844  $value[$i] = NULL;
845  }
846  }
847  if (!isset($value['aclCategory'])) {
848  $value['aclCategory'] = $key;
849  }
850  if (isset($value['filter'])) {
851  if (!preg_match('/^\(.*\)$/', $value['filter'])) {
852  $value['filter'] = '('.$value['filter'].')';
853  }
854  } else {
855  $value['filter'] = NULL;
856  }
857  if (!isset($value['mainAttr'])) {
858  $value['mainAttr'] = 'cn';
859  }
860  if (!isset($value['nameAttr'])) {
861  $value['nameAttr'] = $value['mainAttr'];
862  }
863  if (!isset($value['tabClass'])) {
864  $value['tabClass'] = 'simpleTabs';
865  }
866  $this->data['OBJECTS'][strtoupper($key)] = $value;
867  @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__, $tabclass, "Adding $class as main tab of");
868  if (!isset($this->data['TABS'][$tabclass])) {
869  $this->data['TABS'][$tabclass] = array();
870  }
871  array_unshift($this->data['TABS'][$tabclass], $entry);
872  }
873  }
874  } elseif (class_available($class) && is_subclass_of($class, 'simpleService')) {
875  @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__, $class, "Adding service");
876  if (!isset($this->data['TABS']['SERVERSERVICE'])) {
877  $this->data['TABS']['SERVERSERVICE'] = array();
878  }
879  $this->data['TABS']['SERVERSERVICE'][] = array(
880  'CLASS' => $class,
881  'NAME' => $plInfo['plShortName']
882  );
883  }
884  /* Feed categories */
885  if (isset($plInfo['plCategory'])) {
886  /* Walk through supplied list and feed only translated categories */
887  $cats = array();
888  foreach ($plInfo['plCategory'] as $idx => $data) {
889  $cat = (is_numeric($idx) ? $data : $idx);
890  $cats[] = $cat;
891  if (!isset($this->data['CATEGORIES'][$cat])) {
892  $this->data['CATEGORIES'][$cat] = array( 'classes' => array('0') );
893  }
894  if (!empty($plInfo['plProvidedAcls'])) {
895  $this->data['CATEGORIES'][$cat]['classes'][] = $class;
896  }
897  if (!is_numeric($idx)) {
898  /* Non numeric index means -> base object containing more informations */
899  $this->data['CATEGORIES'][$cat]['description'] = $data['description'];
900  if (!is_array($data['objectClass'])) {
901  $data['objectClass'] = array($data['objectClass']);
902  }
903  $this->data['CATEGORIES'][$cat]['objectClass'] = $data['objectClass'];
904  }
905  }
906  $plInfo['plCategory'] = $cats;
907  }
908  }
909  unset($plInfo);
910  $this->data['CATEGORIES']['all'] = array(
911  'classes' => array('all'),
912  'description' => '*&nbsp;'._('All categories'),
913  'objectClass' => array(),
914  );
915  /* Extract categories definitions from object types */
916  foreach ($this->data['OBJECTS'] as $key => $infos) {
917  @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__, $infos['aclCategory'], "ObjectType $key category");
918  if (strtoupper($infos['aclCategory']) == $key) {
919  $cat = $infos['aclCategory'];
920  if (!isset($this->data['CATEGORIES'][$cat])) {
921  $this->data['CATEGORIES'][$cat] = array('classes' => array('0'));
922  }
923  if (!isset($this->data['CATEGORIES'][$cat]['description'])) {
924  $this->data['CATEGORIES'][$cat]['description'] = $infos['name'];
925  preg_match_all('/objectClass=([^= \)\(]+)/', $infos['filter'], $m);
926  $this->data['CATEGORIES'][$cat]['objectClass'] = $m[1];
927  }
928  }
929  }
930  /* Now that OBJECTS are filled, place tabs in categories */
931  foreach ($plist->info as $class => &$plInfo) {
932  $acl = array();
933  if (isset($plInfo['plCategory'])) {
934  $acl = $plInfo['plCategory'];
935  if (!is_array($acl)) {
936  $acl = array($acl);
937  }
938  }
939  if (isset($plInfo['plObjectType'])) {
940  foreach ($plInfo['plObjectType'] as $key => $value) {
941  if (is_numeric($key)) {
942  /* This is not the main tab */
943  $obj = strtoupper($value);
944  } else {
945  /* This is the main tab */
946  $obj = strtoupper($key);
947  }
948  /* if this is an existing objectType, not just a tab group */
949  if (isset($this->data['OBJECTS'][$obj])) {
950  $cat = $this->data['OBJECTS'][$obj]['aclCategory'];
951  $acl[] = $cat;
952 
953  if (!empty($plInfo['plProvidedAcls'])) {
954  $this->data['CATEGORIES'][$cat]['classes'][] = $class;
955  }
956  if (!in_array($cat, $plInfo['plCategory'])) {
957  $plInfo['plCategory'][] = $cat;
958  }
959  }
960  }
961  }
962  /* Read management info */
963  if (isset($plInfo['plManages'])) {
964  foreach ($plInfo['plManages'] as $type) {
965  $obj = strtoupper($type);
966  if (!isset($this->data['OBJECTS'][$obj])) {
967  continue;
968  }
969  $cat = $this->data['OBJECTS'][$obj]['aclCategory'];
970  $acl[] = $cat;
971 
972  if (!empty($plInfo['plProvidedAcls'])) {
973  $this->data['CATEGORIES'][$cat]['classes'][] = $class;
974  }
975  if (!in_array($cat, $plInfo['plCategory'])) {
976  $plInfo['plCategory'][] = $cat;
977  }
978 
979  if (isset($this->data['OBJECTS'][$obj])) {
980  $this->data['OBJECTS'][$obj]['management'] = $class;
981  if (isset($class::$skipTemplates) && ($class::$skipTemplates == FALSE)) {
982  $this->data['OBJECTS'][$obj]['templateActive'] = TRUE;
983  $this->data['CATEGORIES'][$cat]['classes'][] = 'template';
984  }
985  }
986  }
987  }
988  @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__, join(',', array_unique($acl)), "Class $class categories");
989  /* Feed menu */
990  if (isset($plInfo['plSection'])) {
991  $section = $plInfo['plSection'];
992  if (!is_array($acl)) {
993  $acl = array($acl);
994  }
995  if (!is_numeric(key($acl))) {
996  $acl = array_keys($acl);
997  }
998  if (isset($plInfo['plSelfModify']) && $plInfo['plSelfModify']) {
999  $acl[] = $acl[0].'/'.$class.':self';
1000  }
1001  $acl = join(',', array_unique($acl));
1002 
1003  if (is_array($section)) {
1004  $section = key($section);
1005  if (is_numeric($section)) {
1006  trigger_error("$class have wrong setting in plInfo/plSection");
1007  continue;
1008  }
1009  $this->data['SECTIONS'][$section] = array_change_key_case($plInfo['plSection'][$section], CASE_UPPER);
1010  }
1011  if (!isset($this->data['MENU'][$section])) {
1012  $this->data['MENU'][$section] = array();
1013  }
1014  $attrs = array('CLASS' => $class);
1015  if (!empty($acl)) {
1016  $attrs['ACL'] = $acl;
1017  }
1018  $this->data['MENU'][$section][] = $attrs;
1019  }
1020  if (isset($plInfo['plMenuProvider']) && $plInfo['plMenuProvider']) {
1021  list($sections, $entries) = $class::getMenuEntries();
1022  foreach ($sections as $section => $infos) {
1023  if (!isset($this->data['SECTIONS'][$section])) {
1024  $this->data['SECTIONS'][$section] = array_change_key_case($infos, CASE_UPPER);
1025  }
1026  if (!isset($this->data['MENU'][$section])) {
1027  $this->data['MENU'][$section] = array();
1028  }
1029  }
1030  foreach ($entries as $section => $section_entries) {
1031  foreach ($section_entries as $entry) {
1032  $this->data['MENU'][$section][] = $entry;
1033  }
1034  }
1035  }
1036  }
1037  unset($plInfo);
1038  ksort($this->data['CATEGORIES']);
1039  foreach ($this->data['CATEGORIES'] as $name => &$infos) {
1040  $infos['classes'] = array_unique($infos['classes']);
1041  if (!isset($infos['description'])) {
1042  $infos['description'] = $name;
1043  $infos['objectClass'] = array();
1044  }
1045  }
1046  unset($infos);
1047  $this->data['SECTIONS']['personal'] = array('NAME' => _('My account'), 'PRIORITY' => 40);
1048  $personal = array();
1049  foreach ($this->data['TABS']['USERTABS'] as $tab) {
1050  $personal[] = array('CLASS' => $tab['CLASS'], 'ACL' => 'user/'.$tab['CLASS'].':self');
1051  }
1052  if (!isset($this->data['MENU']['personal'])) {
1053  $this->data['MENU']['personal'] = $personal;
1054  } else {
1055  $this->data['MENU']['personal'] = array_merge($personal, $this->data['MENU']['personal']);
1056  }
1057  uasort($this->data['SECTIONS'],
1058  function ($a, $b)
1059  {
1060  if ($a['PRIORITY'] == $b['PRIORITY']) {
1061  return 0;
1062  }
1063  return (($a['PRIORITY'] < $b['PRIORITY']) ? -1 : 1);
1064  }
1065  );
1066  }
1067 }
1068 ?>
const CACHE_DIR
Global cache dir.
Definition: variables.inc:55
cred_decrypt($input, $password)
Decrypt a string with RIJNDAEL_128.
Definition: functions.inc:2423
const CLASS_CACHE
name of the class.cache file
Definition: variables.inc:85
This class contains all function to manage ldap multiplexer.
load_servers()
Load server information from config/LDAP.
get_cfg_value($name, $default= '')
Get a configuration value from the config.
set_current($name)
Set the current location.
This class contains all the function needed to make list of plugin and manage them.
del_lock($object)
Remove a lock for object(s)
Definition: functions.inc:670
__construct($filename, $basedir= '')
Class constructor of the config class.
const CONFIGRDN
FusionDirectory config object RDN.
tag_open($parser, $tag, $attrs)
Open xml tag when parsing the xml config.
static set($name, $value)
Set a value in a session.
ldap_init($server, $base, $binddn= '', $pass= '')
Initialize a LDAP connection.
Definition: functions.inc:445
static global_un_set($name)
Unset a session.
static global_set($name, $value)
Set a value in a session.
get_credentials($creds)
Get the password when needed from the config file.
Parent class for all exceptions thrown in FusionDirectory.
get_ldap_link($sizelimit=FALSE)
Get a LDAP link object.
DEBUG($level, $line, $function, $file, $data, $info= '')
Debug level action.
Definition: functions.inc:200
initLanguage($lang=NULL)
Definition: functions.inc:2530
check_and_reload($force=FALSE)
Check and reload the configuration.
check_session_lifetime()
Check if session lifetime matches session.gc_maxlifetime.
static global_get($name)
Accessor of a session var.
static display($s_title, $s_message, $i_type=INFO_DIALOG)
Display a message dialog.
convert_department_dn($dn, $base=NULL)
Convert a department DN to a sub-directory style list.
Definition: functions.inc:959
const DEBUG_CONFIG
Definition: functions.inc:42
$current
Store configuration for current location.
static open($dn, $type)
Create the tab object for the given dn.
searchHooks($class, $value)
Search for hooks.
static global_is_set($name)
Check if a session is defined.
This class is responsible for parsing and querying the fusiondirectory configuration file...
static is_set($name)
Check if the name of the session is set.
get_departments()
Store the departments from ldap in $this->departments.
snapshotEnabled()
Check if snapshot are enabled.
tag_close($parser, $tag)
Close xml tag when parsing the xml config.
add_lock($object, $user)
Add a lock for object(s)
Definition: functions.inc:600
class_available($name)
Checks if a class is available.
Definition: functions.inc:130
parse($filename)
Parse the given configuration file.