FusionDirectory
 All Data Structures Files Functions Variables
functions.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-2016 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 
27 /* Define common locations and variables */
28 require_once ('variables.inc');
29 
30 /* Include required files */
31 require_once (CACHE_DIR.'/'.CLASS_CACHE);
32 require_once ('functions_debug.inc');
33 require_once ('accept-to-gettext.inc');
34 
35 /* Define constants for debugging */
36 define ('DEBUG_TRACE', 1);
37 define ('DEBUG_LDAP', 2);
38 define ('DEBUG_DB', 4);
39 define ('DEBUG_SHELL', 8);
40 define ('DEBUG_POST', 16);
41 define ('DEBUG_SESSION', 32);
42 define ('DEBUG_CONFIG', 64);
43 define ('DEBUG_ACL', 128);
44 define ('DEBUG_SI', 256);
45 define ('DEBUG_MAIL', 512);
46 define ('DEBUG_FAI', 1024); /* FAI (incomplete) */
47 
48 /* Define shadow states */
49 define ('POSIX_ACCOUNT_EXPIRED', 1);
50 define ('POSIX_WARN_ABOUT_EXPIRATION', 2);
51 define ('POSIX_FORCE_PASSWORD_CHANGE', 4);
52 define ('POSIX_DISALLOW_PASSWORD_CHANGE', 8);
53 
54 /* Rewrite german 'umlauts' and spanish 'accents'
55  to get better results */
56 $REWRITE = array( "ä" => "ae",
57  "ö" => "oe",
58  "ü" => "ue",
59  "Ä" => "Ae",
60  "Ö" => "Oe",
61  "Ü" => "Ue",
62  "ß" => "ss",
63  "á" => "a",
64  "é" => "e",
65  "í" => "i",
66  "ó" => "o",
67  "ú" => "u",
68  "Á" => "A",
69  "É" => "E",
70  "Í" => "I",
71  "Ó" => "O",
72  "Ú" => "U",
73  "ñ" => "ny",
74  "Ñ" => "Ny" );
75 
76 
86 function __fusiondirectory_autoload($class_name)
87 {
88  global $class_mapping, $BASE_DIR, $config;
89 
90  if ($class_mapping === NULL) {
91  if (isset($config) && is_object($config) &&
92  $config->get_cfg_value('displayerrors') == 'TRUE') {
93  list($trace,) = html_trace();
94  echo $trace;
95  echo "<br/>\n";
96  }
97  echo sprintf(_("Fatal error: no class locations defined - please run '%s' to fix this"), "<b>fusiondirectory-setup --update-cache</b>");
98  exit;
99  }
100 
101  /* Do not try to autoload smarty classes */
102  if (strpos($class_name, 'Smarty_') === 0) {
103  return;
104  }
105 
106  if (isset($class_mapping["$class_name"])) {
107  require_once($BASE_DIR.'/'.$class_mapping["$class_name"]);
108  } else {
109  @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__, $class_name, 'Could not load');
110  if (isset($config) && is_object($config) &&
111  $config->get_cfg_value('displayerrors') == 'TRUE') {
112  list($trace,) = html_trace();
113  echo $trace;
114  echo "<br/>\n";
115  }
116  echo sprintf(_("Fatal error: cannot instantiate class '%s' - try running '%s' to fix this"), $class_name, "<b>fusiondirectory-setup --update-cache</b>");
117  exit;
118  }
119 }
120 spl_autoload_register('__fusiondirectory_autoload');
121 
122 
130 function class_available($name)
131 {
132  global $class_mapping;
133  return isset($class_mapping[$name]);
134 }
135 
136 
146 function plugin_available($plugin)
147 {
148  global $class_mapping, $BASE_DIR;
149 
150  if (!isset($class_mapping[$plugin])) {
151  return FALSE;
152  } else {
153  return is_readable($BASE_DIR.'/'.$class_mapping[$plugin]);
154  }
155 }
156 
160 function load_plist ($ldap_available = TRUE)
161 {
162  global $config, $plist;
163  if (!session::global_is_set('plist')) {
164  /* Initially load all classes */
165  load_all_classes();
166 
167  $plist = new pluglist();
168  session::global_set('plist', $plist);
169  $config->loadPlist($plist);
170  if ($ldap_available) {
171  $config->get_departments();
172  $config->make_idepartments();
173  }
174  }
175  return session::global_get('plist');
176 }
177 
178 
190 function make_seed()
191 {
192  list($usec, $sec) = explode(' ', microtime());
193  return (float) $sec + ((float) $usec * 100000);
194 }
195 
196 
219 function DEBUG($level, $line, $function, $file, $data, $info = '')
220 {
221  static $first = TRUE;
222  if (($_SERVER['REQUEST_METHOD'] == 'POST') && preg_match('/index.php$/', $_SERVER['REQUEST_URI'])) {
223  return;
224  }
225  if (session::global_get('DEBUGLEVEL') & $level) {
226  if ($first) {
227  echo '<div id="debug-handling" class="notice">'.
228  '<img src="geticon.php?context=status&amp;icon=dialog-information&amp;size=22" alt="info icon" style="vertical-align:middle;margin-right:.2em;"/>'.
229  'There is some debug output '.
230  '<button onClick="javascript:$$(\'div.debug_div\').each(function (a) { a.toggle(); });">Toggle</button>'.
231  '</div>';
232  $first = FALSE;
233  }
234  $output = "DEBUG[$level] ";
235  if ($function != '') {
236  $output .= "($file:$function():$line) - $info: ";
237  } else {
238  $output .= "($file:$line) - $info: ";
239  }
240  echo '<div class="debug_div">';
241  echo $output;
242  if (is_array($data)) {
243  print_a($data);
244  } else {
245  echo "'$data'";
246  }
247  echo "</div>\n";
248  }
249 }
250 
251 
266 {
267  /* Try to use users primary language */
268  global $config;
269  $ui = get_userinfo();
270  if (isset($ui) && ($ui !== NULL) && ($ui->language != '')) {
271  return $ui->language.'.UTF-8';
272  }
273 
274  /* Check for global language settings in configuration */
275  if (isset($config) && ($config->get_cfg_value('language') != '')) {
276  $lang = $config->get_cfg_value('language');
277  if (!preg_match('/utf/i', $lang)) {
278  $lang .= '.UTF-8';
279  }
280  return $lang;
281  }
282 
283  /* Load supported languages */
284  $gosa_languages = get_languages();
285 
286  /* Move supported languages to flat list */
287  $langs = array();
288  foreach (array_keys($gosa_languages) as $lang) {
289  $langs[] = $lang.'.UTF-8';
290  }
291  /* Return gettext based string */
292  return al2gt($langs, 'text/html');
293 }
294 
315 function get_template_path($filename = '', $plugin = FALSE, $path = '')
316 {
317  global $config, $BASE_DIR;
318  $default_theme = 'breezy';
319 
320  /* Set theme */
321  if (isset ($config)) {
322  $theme = $config->get_cfg_value('theme', $default_theme);
323  } else {
324  $theme = $default_theme;
325  }
326 
327  /* Return path for empty filename */
328  if ($filename == '') {
329  return "themes/$theme/";
330  }
331 
332  /* Return plugin dir or root directory? */
333  if ($plugin) {
334  if ($path == '') {
335  $path = session::global_get('plugin_dir');
336  $nf = preg_replace('!^'.$BASE_DIR.'/!', '', preg_replace('/^\.\.\//', '', $path));
337  } else {
338  $nf = preg_replace('!^'.$BASE_DIR.'/!', '', $path);
339  }
340  $paths = array(
341  "$BASE_DIR/ihtml/themes/$theme/$nf/$filename",
342  "$BASE_DIR/ihtml/themes/$default_theme/$nf/$filename",
343  "$BASE_DIR/ihtml/themes/default/$nf/$filename",
344  $path."/$filename"
345  );
346  } else {
347  $paths = array(
348  "themes/$theme/$filename",
349  "$BASE_DIR/ihtml/themes/$theme/$filename",
350  "themes/$default_theme/$filename",
351  "$BASE_DIR/ihtml/themes/$default_theme/$filename",
352  "themes/default/$filename",
353  "$BASE_DIR/ihtml/themes/default/$filename",
354  $filename
355  );
356  }
357 
358  foreach ($paths as $path) {
359  if (file_exists($path)) {
360  return $path;
361  }
362  }
363 
364  return end($paths);
365 }
366 
367 
378 function array_remove_entries(array $needles, array $haystack)
379 {
380  return array_values(array_diff($haystack, $needles));
381 }
382 
383 
394 function array_remove_entries_ics(array $needles, array $haystack)
395 {
396  // strcasecmp will work, because we only compare ASCII values here
397  return array_values(array_udiff($haystack, $needles, 'strcasecmp'));
398 }
399 
412 function array_merge_unique($ar1, $ar2)
413 {
414  if (!is_array($ar1) || !is_array($ar2)) {
415  trigger_error('Specified parameter(s) are not valid arrays.');
416  } else {
417  return array_values(array_unique(array_merge($ar1, $ar2)));
418  }
419 }
420 
421 
429 function fusiondirectory_log ($message)
430 {
431  global $ui;
432 
433  /* Preset to something reasonable */
434  $username = '[unauthenticated]';
435 
436  /* Replace username if object is present */
437  if (isset($ui)) {
438  if ($ui->uid != '') {
439  $username = '['.$ui->uid.']';
440  } else {
441  $username = '[unknown]';
442  }
443  }
444 
445  syslog(LOG_INFO, "FusionDirectory $username: $message");
446 }
447 
448 
464 function ldap_init ($server, $base, $binddn = '', $pass = '')
465 {
466  global $config;
467 
468  $ldap = new LDAP ($binddn, $pass, $server,
469  isset($config->current['LDAPFOLLOWREFERRALS']) && $config->current['LDAPFOLLOWREFERRALS'] == 'TRUE',
470  isset($config->current['LDAPTLS']) && $config->current['LDAPTLS'] == 'TRUE');
471 
472  /* Sadly we've no proper return values here. Use the error message instead. */
473  if (!$ldap->success()) {
474  msg_dialog::display(_('Fatal error'),
475  sprintf(_("FATAL: Error when connecting the LDAP. Server said '%s'."), $ldap->get_error()),
476  FATAL_ERROR_DIALOG);
477  exit();
478  }
479 
480  /* Preset connection base to $base and return to caller */
481  $ldap->cd ($base);
482  return $ldap;
483 }
484 
494 function ldap_get_user ($username)
495 {
496  global $config;
497 
498  /* look through the entire ldap */
499  $ldap = $config->get_ldap_link();
500  if (!$ldap->success()) {
501  msg_dialog::display(_('LDAP error'),
502  msgPool::ldaperror($ldap->get_error(), '', LDAP_AUTH).'<br/><br/>'.session::get('errors'),
503  FATAL_ERROR_DIALOG);
504  exit();
505  }
506 
507  $allowed_attributes = array('uid','mail');
508  $verify_attr = array();
509  $tmp = explode(',', $config->get_cfg_value('loginAttribute'));
510  foreach ($tmp as $attr) {
511  if (in_array($attr, $allowed_attributes)) {
512  $verify_attr[] = $attr;
513  }
514  }
515 
516  if (count($verify_attr) == 0) {
517  $verify_attr = array('uid');
518  }
519  $tmp = $verify_attr;
520  $tmp[] = 'uid';
521  $filter = '';
522  foreach ($verify_attr as $attr) {
523  $filter .= '('.$attr.'='.$username.')';
524  }
525  $filter = '(&(|'.$filter.')(objectClass=inetOrgPerson))';
526  $ldap->cd($config->current['BASE']);
527  $ldap->search($filter, $tmp);
528 
529  /* get results, only a count of 1 is valid */
530  if ($ldap->count() == 0) {
531  /* user not found */
532  return FALSE;
533  } elseif ($ldap->count() != 1) {
534  /* found more than one matching id */
535  return _('Login (uid) is not unique inside the LDAP tree. Please contact your administrator.');
536  }
537 
538  /* LDAP schema is not case sensitive. Perform additional check. */
539  $attrs = $ldap->fetch();
540  $success = FALSE;
541  foreach ($verify_attr as $attr) {
542  if (isset($attrs[$attr][0]) && $attrs[$attr][0] == $username) {
543  $success = TRUE;
544  }
545  }
546  $ldap->disconnect();
547  if (!$success) {
548  return FALSE;
549  }
550 
551  return new userinfo($attrs['dn']);
552 }
553 
566 function ldap_login_user ($username, $password)
567 {
568  global $config;
569 
570  $ui = ldap_get_user($username);
571 
572  if ($ui === FALSE) {
573  return NULL;
574  } elseif (is_string($ui)) {
575  msg_dialog::display(_('Internal error'), $ui, FATAL_ERROR_DIALOG);
576  return NULL;
577  }
578 
579  /* password check, bind as user with supplied password */
580  $ldapObj = new LDAP($ui->dn, $password, $config->current['SERVER'],
581  isset($config->current['LDAPFOLLOWREFERRALS']) &&
582  $config->current['LDAPFOLLOWREFERRALS'] == 'TRUE',
583  isset($config->current['LDAPTLS'])
584  && $config->current['LDAPTLS'] == 'TRUE'
585  );
586  $ldap = new ldapMultiplexer($ldapObj);
587  if (!$ldap->success()) {
588  return NULL;
589  }
590  if (class_available('ppolicyAccount')) {
591  $ldap->cd($config->current['BASE']);
592  $ldap->search('(objectClass=*)', array(), 'one');
593  if (!$ldap->success()) {
595  _('Authentication error'),
596  _('It seems your user password has expired. Please use <a href="recovery.php">password recovery</a> to change it.'),
597  ERROR_DIALOG
598  );
599  return NULL;
600  }
601  }
602 
603  /* Username is set, load subtreeACL's now */
604  $ui->loadACL();
605 
606  return $ui;
607 }
608 
619 function add_lock($object, $user)
620 {
621  global $config;
622 
623  /* Remember which entries were opened as read only, because we
624  don't need to remove any locks for them later.
625  */
626  if (!session::global_is_set('LOCK_CACHE')) {
627  session::global_set('LOCK_CACHE', array(''));
628  }
629  if (is_array($object)) {
630  foreach ($object as $obj) {
631  add_lock($obj, $user);
632  }
633  return;
634  }
635 
636  $cache = &session::global_get_ref('LOCK_CACHE');
637  if (isset($_POST['open_readonly'])) {
638  $cache['READ_ONLY'][$object] = TRUE;
639  return;
640  }
641  if (isset($cache['READ_ONLY'][$object])) {
642  unset($cache['READ_ONLY'][$object]);
643  }
644 
645  /* Just a sanity check... */
646  if ($object == '' || $user == '') {
647  msg_dialog::display(_('Internal error'), _('Error while adding a lock. Contact the developers!'), ERROR_DIALOG);
648  return;
649  }
650 
651  /* Check for existing entries in lock area */
652  $ldap = $config->get_ldap_link();
653  $ldap->cd(get_ou('lockRDN').get_ou('fusiondirectoryRDN').$config->current['BASE']);
654  $ldap->search('(&(objectClass=fdLockEntry)(fdUserDn='.ldap_escape_f($user).')(fdObjectDn='.base64_encode($object).'))',
655  array('fdUserDn'));
656  if (!$ldap->success()) {
657  msg_dialog::display(_('Configuration error'), sprintf(_('Cannot create locking information in LDAP tree. Please contact your administrator!').'<br><br>'._('LDAP server returned: %s'), '<br><br><i>'.$ldap->get_error().'</i>'), ERROR_DIALOG);
658  return;
659  }
660 
661  /* Add lock if none present */
662  if ($ldap->count() == 0) {
663  $attrs = array();
664  $name = md5($object);
665  $ldap->cd('cn='.$name.','.get_ou('lockRDN').get_ou('fusiondirectoryRDN').$config->current['BASE']);
666  $attrs = array(
667  'objectClass' => 'fdLockEntry',
668  'fdUserDn' => $user,
669  'fdObjectDn' => base64_encode($object),
670  'cn' => $name,
671  'fdLockTimestamp' => LdapGeneralizedTime::toString(new DateTime('now')),
672  );
673  $ldap->add($attrs);
674  if (!$ldap->success()) {
675  msg_dialog::display(_('LDAP error'), msgPool::ldaperror($ldap->get_error(), "cn=$name,".get_ou('lockRDN').get_ou('fusiondirectoryRDN').$config->current['BASE'], 0), LDAP_ERROR);
676  return;
677  }
678  }
679 }
680 
681 
689 function del_lock ($object)
690 {
691  global $config;
692 
693  if (is_array($object)) {
694  foreach ($object as $obj) {
695  del_lock($obj);
696  }
697  return;
698  }
699 
700  /* Sanity check */
701  if ($object == '') {
702  return;
703  }
704 
705  /* If this object was opened in read only mode then
706  skip removing the lock entry, there wasn't any lock created.
707  */
708  if (session::global_is_set('LOCK_CACHE')) {
709  $cache = &session::global_get_ref('LOCK_CACHE');
710  if (isset($cache['READ_ONLY'][$object])) {
711  unset($cache['READ_ONLY'][$object]);
712  return;
713  }
714  }
715 
716  /* Check for existance and remove the entry */
717  $ldap = $config->get_ldap_link();
718  $ldap->cd(get_ou('lockRDN').get_ou('fusiondirectoryRDN').$config->current['BASE']);
719  $ldap->search('(&(objectClass=fdLockEntry)(fdObjectDn='.base64_encode($object).'))', array('fdObjectDn'));
720  $attrs = $ldap->fetch();
721  if (!$ldap->success()) {
722  msg_dialog::display(_('LDAP error'), msgPool::ldaperror($ldap->get_error(), $ldap->getDN(), LDAP_DEL, ERROR_DIALOG));
723  return;
724  } elseif (!empty($attrs['dn'])) {
725  $ldap->rmdir($attrs['dn']);
726  }
727 }
728 
729 
738 function del_user_locks($userdn)
739 {
740  global $config;
741 
742  /* Get LDAP ressources */
743  $ldap = $config->get_ldap_link();
744  $ldap->cd(get_ou('lockRDN').get_ou('fusiondirectoryRDN').$config->current['BASE']);
745 
746  /* Remove all objects of this user, drop errors silently in this case. */
747  $ldap->search('(&(objectClass=fdLockEntry)(fdUserDn='.ldap_escape_f($userdn).'))', array('fdUserDn'));
748  while ($attrs = $ldap->fetch()) {
749  $ldap->rmdir($attrs['dn']);
750  }
751 }
752 
753 
764 function get_lock($object)
765 {
766  /* Sanity check */
767  if ($object == '') {
768  msg_dialog::display(_('Internal error'), _('Error while adding a lock. Contact the developers!'), ERROR_DIALOG);
769  return FALSE;
770  }
771 
772  /* Allow readonly access, the plugin constructor will restrict the acls */
773  if (isset($_POST['open_readonly'])) {
774  return '';
775  }
776 
777  $locks = get_locks($object);
778  if ($locks === FALSE) {
779  return FALSE;
780  } elseif (empty($locks)) {
781  return '';
782  } else {
783  return $locks[0]['user'];
784  }
785 }
786 
787 
801 function get_locks($objects, $allow_readonly = FALSE)
802 {
803  global $config;
804 
805  if (is_array($objects) && count($objects == 1)) {
806  $objects = reset($objects);
807  }
808  if (is_array($objects)) {
809  if ($allow_readonly) {
810  trigger_error('Read only is not possible for several objects');
811  }
812  $filter = '(&(objectClass=fdLockEntry)(|';
813  foreach ($objects as $obj) {
814  $filter .= '(fdObjectDn='.base64_encode($obj).')';
815  }
816  $filter .= '))';
817  } else {
818  if ($allow_readonly && isset($_POST['open_readonly'])) {
819  /* If readonly is allowed and asked and there is only one object, bypass lock detection */
820  return array();
821  }
822  $filter = '(&(objectClass=fdLockEntry)(fdObjectDn='.base64_encode($objects).'))';
823  }
824 
825  /* Get LDAP link, check for presence of the lock entry */
826  $ldap = $config->get_ldap_link();
827  $ldap->cd(get_ou('lockRDN').get_ou('fusiondirectoryRDN').$config->current['BASE']);
828  $ldap->search($filter, array('fdUserDn','fdObjectDn', 'fdLockTimestamp'));
829  if (!$ldap->success()) {
830  msg_dialog::display(_('LDAP error'), msgPool::ldaperror($ldap->get_error(), '', LDAP_SEARCH), LDAP_ERROR);
831  return FALSE;
832  }
833 
834  $locks = array();
835  while ($attrs = $ldap->fetch()) {
836  $locks[] = array(
837  'dn' => $attrs['dn'],
838  'object' => base64_decode($attrs['fdObjectDn'][0]),
839  'user' => $attrs['fdUserDn'][0],
840  'timestamp' => LdapGeneralizedTime::fromString($attrs['fdLockTimestamp'][0]),
841  );
842  }
843 
844  if (!is_array($objects) && (count($locks) > 1)) {
845  /* Hmm. We're removing broken LDAP information here and issue a warning. */
846  msg_dialog::display(_('Warning'), _('Found multiple locks for object to be locked. This should not happen - cleaning up multiple references.'), WARNING_DIALOG);
847 
848  /* Clean up these references now... */
849  foreach ($locks as $lock) {
850  $ldap->rmdir($lock['dn']);
851  }
852 
853  return FALSE;
854  }
855 
856  return $locks;
857 }
858 
865 function check_sizelimit()
866 {
867  /* Ignore dialog? */
868  if (session::global_is_set('size_ignore') && session::global_get('size_ignore')) {
869  return '';
870  }
871 
872  /* Eventually show dialog */
873  if (session::is_set('limit_exceeded') && session::get('limit_exceeded')) {
874  $smarty = get_smarty();
875  $smarty->assign('warning', sprintf(_('The size limit of %d entries is exceed!'),
876  session::global_get('size_limit')));
877  $smarty->assign('limit_message', sprintf(_('Set the new size limit to %s and show me this message if the limit still exceeds'), '<input type="text" name="new_limit" maxlength="10" size="5" value="'.(session::global_get('size_limit') + 100).'"/>'));
878  return $smarty->fetch(get_template_path('sizelimit.tpl'));
879  }
880 
881  return '';
882 }
883 
891 {
892  if (session::global_is_set('size_limit') && session::global_get('size_limit') >= 10000000 ||
893  (session::is_set('limit_exceeded') && session::get('limit_exceeded'))) {
894  $config = '<input type="submit" name="edit_sizelimit" value="'._('Configure').'"/>';
895  } else {
896  $config = '';
897  }
898  if (session::is_set('limit_exceeded') && session::get('limit_exceeded')) {
899  return '('._('incomplete').") $config";
900  }
901  return '';
902 }
903 
904 
908 function eval_sizelimit()
909 {
910  if (isset($_POST['set_size_action']) && isset($_POST['action'])) {
911  switch($_POST['action']) {
912  case 'newlimit':
913  if (isset($_POST['new_limit']) && tests::is_id($_POST['new_limit'])) {
914  session::global_set('size_limit', validate($_POST['new_limit']));
915  session::set('size_ignore', FALSE);
916  }
917  break;
918  case 'ignore':
919  session::global_set('size_limit', 0);
920  session::global_set('size_ignore', TRUE);
921  break;
922  case 'limited':
923  session::global_set('size_ignore', TRUE);
924  break;
925  default:
926  break;
927  }
928  }
929 
930  /* Allow fallback to dialog */
931  if (isset($_POST['edit_sizelimit'])) {
932  session::global_set('size_ignore', FALSE);
933  }
934 }
935 
941 function &get_userinfo()
942 {
943  global $ui;
944 
945  return $ui;
946 }
947 
953 function &get_smarty()
954 {
955  global $smarty;
956 
957  return $smarty;
958 }
959 
978 function convert_department_dn($dn, $base = NULL)
979 {
980  global $config;
981 
982  if ($base == NULL) {
983  $base = $config->current['BASE'];
984  }
985 
986  /* Build a sub-directory style list of the tree level
987  specified in $dn */
988  $dn = preg_replace('/'.preg_quote($base, '/')."$/i", '', $dn);
989  if (empty($dn)) {
990  return '/';
991  }
992 
993  $dep = '';
994  foreach (explode(',', $dn) as $rdn) {
995  $dep = preg_replace("/^[^=]+=/", '', $rdn).'/'.$dep;
996  }
997 
998  /* Return and remove accidently trailing slashes */
999  return trim($dep, '/');
1000 }
1001 
1020 function get_ou($name)
1021 {
1022  global $config;
1023 
1024  $map = array(
1025  'fusiondirectoryRDN' => 'ou=fusiondirectory,',
1026  'lockRDN' => 'ou=locks,',
1027  'recoveryTokenRDN' => 'ou=recovery,',
1028  'reminderTokenRDN' => 'ou=reminder,',
1029  'roleRDN' => 'ou=roles,',
1030  'ogroupRDN' => 'ou=groups,',
1031  'applicationRDN' => 'ou=apps,',
1032  'systemRDN' => 'ou=systems,',
1033  'serverRDN' => 'ou=servers,ou=systems,',
1034  'terminalRDN' => 'ou=terminals,ou=systems,',
1035  'workstationRDN' => 'ou=workstations,ou=systems,',
1036  'printerRDN' => 'ou=printers,ou=systems,',
1037  'phoneRDN' => 'ou=phones,ou=systems,',
1038  'componentRDN' => 'ou=netdevices,ou=systems,',
1039  'mobilePhoneRDN' => 'ou=mobile,ou=systems,',
1040 
1041  'inventoryRDN' => 'ou=inventory,',
1042 
1043  'ipmiRDN' => 'ou=ipmi,',
1044 
1045  'faxBlocklistRDN' => 'ou=gofax,ou=systems,',
1046  'aclRoleRDN' => 'ou=aclroles,',
1047  'phoneMacroRDN' => 'ou=macros,ou=asterisk,ou=configs,ou=systems,',
1048  'phoneConferenceRDN' => 'ou=conferences,ou=asterisk,ou=configs,ou=systems,',
1049 
1050  'faiBaseRDN' => 'ou=fai,ou=configs,ou=systems,',
1051  'faiScriptRDN' => 'ou=scripts,',
1052  'faiHookRDN' => 'ou=hooks,',
1053  'faiTemplateRDN' => 'ou=templates,',
1054  'faiVariableRDN' => 'ou=variables,',
1055  'faiProfileRDN' => 'ou=profiles,',
1056  'faiPackageRDN' => 'ou=packages,',
1057  'faiPartitionRDN' => 'ou=disk,',
1058 
1059  'debconfRDN' => 'ou=debconf,',
1060 
1061  'supannStructuresRDN' => 'ou=structures,',
1062 
1063  'sudoRDN' => 'ou=sudoers,',
1064 
1065  'netgroupRDN' => 'ou=netgroup,',
1066 
1067  'deviceRDN' => 'ou=devices,',
1068 
1069  'aliasRDN' => 'ou=alias,',
1070 
1071  'dsaRDN' => 'ou=dsa,',
1072 
1073  'mimetypeRDN' => 'ou=mime,'
1074  );
1075 
1076  /* Preset ou... */
1077  if ($config->get_cfg_value($name, '_not_set_') != '_not_set_') {
1078  $ou = $config->get_cfg_value($name);
1079  } elseif (isset($map[$name])) {
1080  $ou = $map[$name];
1081  return $ou;
1082  } else {
1083  return NULL;
1084  }
1085 
1086  if ($ou != '') {
1087  if (!preg_match('/^[^=]+=[^=]+/', $ou)) {
1088  $ou = "ou=$ou";
1089  } else {
1090  $ou = "$ou";
1091  }
1092 
1093  if (preg_match('/'.preg_quote($config->current['BASE'], '/').'$/', $ou)) {
1094  return $ou;
1095  } else {
1096  if (preg_match('/,$/', $ou)) {
1097  return $ou;
1098  } else {
1099  return "$ou,";
1100  }
1101  }
1102  } else {
1103  return '';
1104  }
1105 }
1106 
1114 function get_people_ou()
1115 {
1116  return get_ou('userRDN');
1117 }
1118 
1131 {
1132  global $config;
1133 
1134  $pattern = "/^[^,]+,".preg_quote(get_people_ou(), '/')."/i";
1135  $base = preg_replace($pattern, '', $dn);
1136 
1137  /* Set to base, if we're not on a correct subtree */
1138  if (!isset($config->idepartments[$base])) {
1139  $base = $config->current['BASE'];
1140  }
1141 
1142  return $base;
1143 }
1144 
1145 
1156 {
1157  global $config;
1158 
1159  if (isset($config)) {
1160  return ($config->get_cfg_value('strictNamingRules') == 'TRUE');
1161  }
1162  return TRUE;
1163 }
1164 
1189 function gen_locked_message($locks, $dn, $allow_readonly = FALSE)
1190 {
1191  session::set('dn', $dn);
1192  $remove = FALSE;
1193 
1194  /* Save variables from LOCK_VARS_TO_USE in session - for further editing */
1195  if ( session::is_set('LOCK_VARS_TO_USE') && count(session::get('LOCK_VARS_TO_USE'))) {
1196 
1197  $LOCK_VARS_USED_GET = array();
1198  $LOCK_VARS_USED_POST = array();
1199  $LOCK_VARS_USED_REQUEST = array();
1200  $LOCK_VARS_TO_USE = session::get('LOCK_VARS_TO_USE');
1201 
1202  foreach ($LOCK_VARS_TO_USE as $name) {
1203 
1204  if (empty($name)) {
1205  continue;
1206  }
1207 
1208  foreach ($_POST as $Pname => $Pvalue) {
1209  if (preg_match($name, $Pname)) {
1210  $LOCK_VARS_USED_POST[$Pname] = $_POST[$Pname];
1211  }
1212  }
1213 
1214  foreach ($_GET as $Pname => $Pvalue) {
1215  if (preg_match($name, $Pname)) {
1216  $LOCK_VARS_USED_GET[$Pname] = $_GET[$Pname];
1217  }
1218  }
1219 
1220  foreach ($_REQUEST as $Pname => $Pvalue) {
1221  if (preg_match($name, $Pname)) {
1222  $LOCK_VARS_USED_REQUEST[$Pname] = $_REQUEST[$Pname];
1223  }
1224  }
1225  }
1226  session::set('LOCK_VARS_TO_USE', array());
1227  session::set('LOCK_VARS_USED_GET', $LOCK_VARS_USED_GET);
1228  session::set('LOCK_VARS_USED_POST', $LOCK_VARS_USED_POST);
1229  session::set('LOCK_VARS_USED_REQUEST', $LOCK_VARS_USED_REQUEST);
1230  }
1231 
1232  /* Prepare and show template */
1233  $smarty = get_smarty();
1234  $smarty->assign('allow_readonly', $allow_readonly);
1235  if (is_array($dn)) {
1236  $msg = '<pre>';
1237  foreach ($dn as $sub_dn) {
1238  $msg .= "\n".$sub_dn.', ';
1239  }
1240  $msg = preg_replace("/, $/", "</pre>", $msg);
1241  } else {
1242  $msg = $dn;
1243  }
1244 
1245  $smarty->assign('dn', $msg);
1246  if ($remove) {
1247  $smarty->assign('action', _('Continue anyway'));
1248  } else {
1249  $smarty->assign('action', _('Edit anyway'));
1250  }
1251  $smarty->assign('message', sprintf(_("You're going to edit the LDAP entry/entries %s"), "<b>".$msg."</b>", ""));
1252  $smarty->assign('locks', $locks);
1253 
1254  return $smarty->fetch(get_template_path('islocked.tpl'));
1255 }
1256 
1257 
1271 function to_string ($value)
1272 {
1273  /* If this is an array, generate a text blob */
1274  if (is_array($value)) {
1275  $ret = '';
1276  foreach ($value as $line) {
1277  $ret .= $line."<br>\n";
1278  }
1279  return $ret;
1280  } else {
1281  return $value;
1282  }
1283 }
1284 
1294 function rewrite($s)
1295 {
1296  global $REWRITE;
1297 
1298  foreach ($REWRITE as $key => $val) {
1299  $s = str_replace("$key", "$val", $s);
1300  }
1301 
1302  return $s;
1303 }
1304 
1305 
1314 function dn2base($dn, $ou = NULL)
1315 {
1316  if ($ou === NULL) {
1317  if (get_people_ou() != '') {
1318  $dn = preg_replace('/,'.get_people_ou().'/i', ',', $dn);
1319  }
1320  if (get_ou('groupRDN') != '') {
1321  $dn = preg_replace('/,'.get_ou('groupRDN').'/i', ',', $dn);
1322  }
1323  } else {
1324  $dn = preg_replace("/,$ou/i", ',', $dn);
1325  }
1326 
1327  return preg_replace ('/^[^,]+,/i', '', $dn);
1328 }
1329 
1340 function check_command($cmdline)
1341 {
1342  $cmd = preg_replace("/ .*$/", '', $cmdline);
1343 
1344  /* Check if command exists in filesystem */
1345  if (!file_exists($cmd)) {
1346  return FALSE;
1347  }
1348 
1349  /* Check if command is executable */
1350  if (!is_executable($cmd)) {
1351  return FALSE;
1352  }
1353 
1354  return TRUE;
1355 }
1356 
1368 function print_header($image, $headline, $info = '')
1369 {
1370  $smarty = get_smarty();
1371  $smarty->assign('headline', $headline);
1372  $smarty->assign('headline_image', $image);
1373  $display = '';
1374 
1375  if ($info != '') {
1376  $display .= '<div class="pluginfo">'."\n";
1377  $display .= "$info";
1378  $display .= "</div>\n";
1379  $display .= "<div></div>\n";
1380  }
1381  return $display;
1382 }
1383 
1389 function back_to_main()
1390 {
1391  return '<br><p class="plugbottom"><input type=submit name="password_back" value="'.
1392  msgPool::backButton().'"></p><input type="hidden" name="ignore">';
1393 }
1394 
1402 function normalize_netmask($netmask)
1403 {
1404  /* Check for notation of netmask */
1405  if (!preg_match('/^([0-9]+\.){3}[0-9]+$/', $netmask)) {
1406  $num = (int)($netmask);
1407  $netmask = "";
1408 
1409  for ($byte = 0; $byte < 4; $byte++) {
1410  $result = 0;
1411 
1412  for ($i = 7; $i >= 0; $i--) {
1413  if ($num-- > 0) {
1414  $result += pow(2, $i);
1415  }
1416  }
1417 
1418  $netmask .= $result.".";
1419  }
1420 
1421  return preg_replace('/\.$/', '', $netmask);
1422  }
1423 
1424  return $netmask;
1425 }
1426 
1427 
1452 function netmask_to_bits($netmask)
1453 {
1454  $nm = explode('.', $netmask, 4);
1455 
1456  $res = 0;
1457  for ($n = 0; $n < 4; $n++) {
1458  $start = 255;
1459 
1460  for ($i = 0; $i < 8; $i++) {
1461  if ($start == (int)($nm[$n])) {
1462  $res += 8 - $i;
1463  break;
1464  }
1465  $start -= pow(2, $i);
1466  }
1467  }
1468 
1469  return $res;
1470 }
1471 
1472 
1476 function _recurse_gen_uids($rule, $variables)
1477 {
1478  $result = array();
1479 
1480  if (!count($variables)) {
1481  return array($rule);
1482  }
1483 
1484  reset($variables);
1485  $key = key($variables);
1486  $val = current($variables);
1487  unset($variables[$key]);
1488 
1489  foreach ($val as $possibility) {
1490  $nrule = str_replace("{$key}", $possibility, $rule);
1491  $result = array_merge($result, _recurse_gen_uids($nrule, $variables));
1492  }
1493 
1494  return $result;
1495 }
1496 
1497 
1510 function gen_uids($rule, $attributes)
1511 {
1512  global $config;
1513 
1514  // Attributes should be arrays
1515  foreach ($attributes as $name => $value) {
1516  $attributes[$name] = array($value);
1517  }
1518 
1519  /* Search for keys and fill the variables array with all
1520  possible values for that key. */
1521  $stripped = $rule;
1522  $variables = array();
1523 
1524  for ($pos = 0; preg_match('/%([^%]+)%/', $stripped, $m, PREG_OFFSET_CAPTURE, $pos); ) {
1525  $variables[$pos] = templateHandling::parseMask($m[1][0], $attributes);
1526  $replace = '{'.$pos.'}';
1527  $stripped = substr_replace($stripped, $replace, $m[0][1], strlen($m[0][0]));
1528  $pos = $m[0][1] + strlen($replace);
1529  }
1530 
1531  /* Recurse through all possible combinations */
1532  $proposed = _recurse_gen_uids($stripped, $variables);
1533 
1534  /* Get list of used ID's */
1535  $ldap = $config->get_ldap_link();
1536  $ldap->cd($config->current['BASE']);
1537 
1538  /* Remove used uids and watch out for id tags */
1539  $ret = array();
1540  foreach ($proposed as $uid) {
1541  /* Check for id tag and modify uid if needed */
1542  if (preg_match('/\{id(:|!)(\d+)}/', $uid, $m)) {
1543  $size = $m[2];
1544 
1545  $start = ($m[1] == ":" ? 0 : -1);
1546  for ($i = $start, $p = pow(10, $size) - 1; $i < $p; $i++) {
1547  if ($i == -1) {
1548  $number = "";
1549  } else {
1550  $number = sprintf("%0".$size."d", $i + 1);
1551  }
1552  $res = preg_replace('/{id(:|!)\d+}/', $number, $uid);
1553 
1554  $ldap->search('(uid='.ldap_escape_f(preg_replace('/[{}]/', '', $res)).')', array('dn'));
1555  if ($ldap->count() == 0) {
1556  $uid = $res;
1557  break;
1558  }
1559  }
1560 
1561  /* Remove link if nothing has been found */
1562  $uid = preg_replace('/{id(:|!)\d+}/', '', $uid);
1563  }
1564 
1565  if (preg_match('/\{id#\d+}/', $uid)) {
1566  $size = preg_replace('/^.*{id#(\d+)}.*$/', '\\1', $uid);
1567 
1568  while (TRUE) {
1569  mt_srand((double)microtime() * 1000000);
1570  $number = sprintf("%0".$size."d", mt_rand(0, pow(10, $size) - 1));
1571  $res = preg_replace('/{id#(\d+)}/', $number, $uid);
1572  $ldap->search('(uid='.ldap_escape_f(preg_replace('/[{}]/', '', $res)).')', array('dn'));
1573  if ($ldap->count() == 0) {
1574  $uid = $res;
1575  break;
1576  }
1577  }
1578 
1579  /* Remove link if nothing has been found */
1580  $uid = preg_replace('/{id#\d+}/', '', $uid);
1581  }
1582 
1583  /* Don't assign used ones */
1584  $ldap->search('(uid='.ldap_escape_f(preg_replace('/[{}]/', '', $uid)).')', array('dn'));
1585  if ($ldap->count() == 0) {
1586  /* Add uid, but remove {} first. These are invalid anyway. */
1587  $uid = preg_replace('/[{}]/', '', $uid);
1588  if ($uid != '') {
1589  $ret[] = $uid;
1590  }
1591  }
1592  }
1593 
1594  return array_unique($ret);
1595 }
1596 
1597 
1610 function to_byte($value)
1611 {
1612  $value = strtolower(trim($value));
1613 
1614  if (!is_numeric(substr($value, -1))) {
1615 
1616  switch (substr($value, -1)) {
1617  case 'g':
1618  $mult = 1073741824;
1619  break;
1620  case 'm':
1621  $mult = 1048576;
1622  break;
1623  case 'k':
1624  $mult = 1024;
1625  break;
1626  }
1627 
1628  return $mult * (int)substr($value, 0, -1);
1629  } else {
1630  return $value;
1631  }
1632 }
1633 
1643 function humanReadableSize ($bytes, $precision = 2)
1644 {
1645  $format = array(
1646  _('%sB'),
1647  _('%sKiB'),
1648  _('%sMiB'),
1649  _('%sGiB'),
1650  _('%sTiB'),
1651  _('%sPiB'),
1652  _('%sEiB'),
1653  _('%sZiB'),
1654  _('%sYiB')
1655  );
1656  if ($bytes == 0) {
1657  return sprintf($format[0], '0');
1658  }
1659  $base = log($bytes) / log(1024);
1660 
1661  return sprintf($format[floor($base)], round(pow(1024, $base - floor($base)), $precision));
1662 }
1663 
1664 
1677 function in_array_ics($value, array $items)
1678 {
1679  return preg_grep('/^'.preg_quote($value, '/').'$/i', $items);
1680 }
1681 
1682 
1684 function generate_alphabet($count = 10)
1685 {
1686  $characters = _("*ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789");
1687  $alphabet = "";
1688  $c = 0;
1689 
1690  /* Fill cells with charaters */
1691  for ($i = 0, $l = mb_strlen($characters, 'UTF8'); $i < $l; $i++) {
1692  if ($c == 0) {
1693  $alphabet .= "<tr>";
1694  }
1695 
1696  $ch = mb_substr($characters, $i, 1, "UTF8");
1697  $alphabet .= "<td><a class=\"alphaselect\" href=\"main.php?plug=".
1698  validate($_GET['plug'])."&amp;search=".$ch."\">&nbsp;".$ch."&nbsp;</a></td>";
1699 
1700  if ($c++ == $count) {
1701  $alphabet .= "</tr>";
1702  $c = 0;
1703  }
1704  }
1705 
1706  /* Fill remaining cells */
1707  while ($c++ <= $count) {
1708  $alphabet .= "<td>&nbsp;</td>";
1709  }
1710 
1711  return $alphabet;
1712 }
1713 
1714 
1722 function validate($string)
1723 {
1724  return strip_tags(str_replace('\0', '', $string));
1725 }
1726 
1727 
1738 function rmdirRecursive($path, $followLinks = FALSE)
1739 {
1740  $dir = opendir($path);
1741  while ($entry = readdir($dir)) {
1742  if (is_file($path."/".$entry) || ((!$followLinks) && is_link($path."/".$entry))) {
1743  unlink($path."/".$entry);
1744  } elseif (is_dir($path."/".$entry) && ($entry != '.') && ($entry != '..')) {
1745  rmdirRecursive($path."/".$entry);
1746  }
1747  }
1748  closedir($dir);
1749  return rmdir($path);
1750 }
1751 
1752 
1765 function scan_directory($path, $sort_desc = FALSE)
1766 {
1767  $ret = FALSE;
1768 
1769  /* is this a dir ? */
1770  if (is_dir($path)) {
1771 
1772  /* is this path a readable one */
1773  if (is_readable($path)) {
1774 
1775  /* Get contents and write it into an array */
1776  $ret = array();
1777 
1778  $dir = opendir($path);
1779 
1780  /* Is this a correct result ?*/
1781  if ($dir) {
1782  while ($fp = readdir($dir)) {
1783  $ret[] = $fp;
1784  }
1785  }
1786  }
1787  }
1788  /* Sort array ascending , like scandir */
1789  sort($ret);
1790 
1791  /* Sort descending if parameter is sort_desc is set */
1792  if ($sort_desc) {
1793  $ret = array_reverse($ret);
1794  }
1795 
1796  return $ret;
1797 }
1798 
1799 
1805 function clean_smarty_compile_dir($directory)
1806 {
1807  if (is_dir($directory) && is_readable($directory)) {
1808  // Set revision filename to REVISION
1809  $revision_file = $directory."/REVISION";
1810 
1811  /* Is there a stamp containing the current revision? */
1812  if (file_exists($revision_file)) {
1813  // check for "$config->...['CONFIG']/revision" and the
1814  // contents should match the revision number
1815  if (!compare_revision($revision_file, FD_VERSION)) {
1816  // If revision differs, clean compile directory
1817  foreach (scan_directory($directory) as $file) {
1818  if (($file == ".") || ($file == "..")) {
1819  continue;
1820  }
1821  if (is_file($directory."/".$file)) {
1822  // delete file
1823  if (!unlink($directory."/".$file)) {
1824  msg_dialog::display(_("Internal error"), sprintf(_("File '%s' could not be deleted. Try fusiondirectory-setup --check-directories to fix permissions."), $directory."/".$file), ERROR_DIALOG);
1825  }
1826  }
1827  }
1828  } else {
1829  // Revision matches, nothing to do
1830  }
1831  }
1832  /* If the file does not exists or has just been deleted */
1833  if (!file_exists($revision_file)) {
1834  // create revision file
1835  create_revision($revision_file, FD_VERSION);
1836  }
1837  }
1838 }
1839 
1851 function create_revision($revision_file, $revision)
1852 {
1853  $result = FALSE;
1854 
1855  if (is_dir(dirname($revision_file)) && is_writable(dirname($revision_file))) {
1856  if ($fh = fopen($revision_file, 'w')) {
1857  if (fwrite($fh, $revision)) {
1858  $result = TRUE;
1859  }
1860  fclose($fh);
1861  }
1862  } else {
1863  msg_dialog::display(_('Internal error'), _('Cannot write to revision file!'), ERROR_DIALOG);
1864  }
1865 
1866  return $result;
1867 }
1868 
1879 function compare_revision($revision_file, $revision)
1880 {
1881  // FALSE means revision differs
1882  $result = FALSE;
1883 
1884  if (file_exists($revision_file) && is_readable($revision_file)) {
1885  // Open file
1886  if ($fh = fopen($revision_file, "r")) {
1887  // Compare File contents with current revision
1888  if ($revision == fread($fh, filesize($revision_file))) {
1889  $result = TRUE;
1890  }
1891  // Close file
1892  fclose($fh);
1893  } else {
1894  msg_dialog::display(_('Internal error'), _('Cannot read revision file!'), ERROR_DIALOG);
1895  }
1896  }
1897 
1898  return $result;
1899 }
1900 
1901 
1920 function array_key_ics($ikey, array $items)
1921 {
1922  $tmp = array_change_key_case($items, CASE_LOWER);
1923  $ikey = strtolower($ikey);
1924  if (isset($tmp[$ikey])) {
1925  return $tmp[$ikey];
1926  }
1927 
1928  return '';
1929 }
1930 
1931 
1941 function array_differs($src, $dst)
1942 {
1943  /* If the count is differing, the arrays differ */
1944  if (count ($src) != count ($dst)) {
1945  return TRUE;
1946  }
1947 
1948  return (count(array_diff($src, $dst)) != 0);
1949 }
1950 
1960 function array_differs_recursive($src, $dst)
1961 {
1962  if (is_array($src)) {
1963  if (!is_array($dst)) {
1964  return TRUE;
1965  }
1966  if (count($src) != count($dst)) {
1967  return TRUE;
1968  }
1969  foreach ($src as $key => $value) {
1970  if (!isset($dst[$key])) {
1971  return TRUE;
1972  }
1973  if (array_differs_recursive($dst[$key], $value)) {
1974  return TRUE;
1975  }
1976  }
1977  return FALSE;
1978  }
1979  return ((string)$src != (string)$dst);
1980 }
1981 
1988 function normalizeLdap($input)
1989 {
1990  trigger_error('deprecated, use ldap_escape_f');
1991  return addcslashes($input, '*()\\/');
1992 }
1993 
1999 function check_schema($cfg)
2000 {
2001  $checks = array();
2002 
2003  /* Get objectclasses */
2004  $ldapObj = new LDAP($cfg['admin'], $cfg['password'], $cfg['connection'], FALSE, $cfg['tls']);
2005  $ldap = new ldapMultiplexer($ldapObj);
2006  $objectclasses = $ldap->get_objectclasses(TRUE);
2007  if (count($objectclasses) == 0) {
2008  msg_dialog::display(_('LDAP warning'), _('Cannot get schema information from server. No schema check possible!'), WARNING_DIALOG);
2009  return $checks;
2010  }
2011 
2012  /* This is the default block used for each entry.
2013  * to avoid unset indexes.
2014  */
2015  $def_check = array(
2016  'SCHEMA_FILE' => '',
2017  'CLASSES_REQUIRED' => array(),
2018  'STATUS' => FALSE,
2019  'IS_MUST_HAVE' => FALSE,
2020  'MSG' => '',
2021  'INFO' => ''
2022  );
2023 
2024  /* FusionDirectory core schemas */
2025 
2026  /* core-fd */
2027  $checks['core-fd'] = $def_check;
2028  $checks['core-fd']['SCHEMA_FILE'] = 'core-fd.schema';
2029  $checks['core-fd']['CLASSES_REQUIRED'] = array('fdLockEntry');
2030  $checks['core-fd']['IS_MUST_HAVE'] = TRUE;
2031  $checks['core-fd']['INFO'] = _('Main FusionDirectory schema');
2032 
2033  /* core-fd-conf */
2034  $checks['core-fd-conf'] = $def_check;
2035  $checks['core-fd-conf']['SCHEMA_FILE'] = 'core-fd-conf.schema';
2036  $checks['core-fd-conf']['CLASSES_REQUIRED'] = array('fusionDirectoryConf');
2037  $checks['core-fd-conf']['IS_MUST_HAVE'] = TRUE;
2038  $checks['core-fd-conf']['INFO'] = _('Schema used to store FusionDirectory configuration');
2039 
2040  /* ldapns */
2041  $checks['ldapns'] = $def_check;
2042  $checks['ldapns']['SCHEMA_FILE'] = 'ldapns.schema';
2043  $checks['ldapns']['CLASSES_REQUIRED'] = array('hostObject');
2044  $checks['ldapns']['IS_MUST_HAVE'] = FALSE;
2045  $checks['ldapns']['INFO'] = _('Used to store trust mode information in users or groups.');
2046 
2047  /* template-fd */
2048  $checks['template-fd'] = $def_check;
2049  $checks['template-fd']['SCHEMA_FILE'] = 'template-fd.schema';
2050  $checks['template-fd']['CLASSES_REQUIRED'] = array('fdTemplate');
2051  $checks['template-fd']['IS_MUST_HAVE'] = FALSE;
2052  $checks['template-fd']['INFO'] = _('Used to store templates.');
2053 
2054  if (class_available('posixAccount')) {
2055  /* nis */
2056  $checks['nis'] = $def_check;
2057  $checks['nis']['SCHEMA_FILE'] = 'nis.schema';
2058  $checks['nis']['CLASSES_REQUIRED'] = array('posixAccount');
2059  $checks['nis']['IS_MUST_HAVE'] = FALSE;
2060  $checks['nis']['INFO'] = _('Used to store POSIX information.');
2061  }
2062 
2063  foreach ($checks as $name => $value) {
2064  foreach ($value['CLASSES_REQUIRED'] as $class) {
2065  if (!isset($objectclasses[$class])) {
2066  $checks[$name]['STATUS'] = FALSE;
2067  if ($value['IS_MUST_HAVE']) {
2068  $checks[$name]['MSG'] = sprintf(_('Missing required object class "%s"!'), $class);
2069  } else {
2070  $checks[$name]['MSG'] = sprintf(_('Missing optional object class "%s"!'), $class);
2071  }
2072  } else {
2073  $checks[$name]['STATUS'] = TRUE;
2074  $checks[$name]['MSG'] = sprintf(_('Class(es) available'));
2075  }
2076  }
2077  }
2078 
2079  $checks['posixGroup'] = $def_check;
2080  $checks['posixGroup']['SCHEMA_FILE'] = 'nis.schema';
2081  $checks['posixGroup']['CLASSES_REQUIRED'] = array('posixGroup');
2082  $checks['posixGroup']['STATUS'] = TRUE;
2083  $checks['posixGroup']['MSG'] = '';
2084  $checks['posixGroup']['INFO'] = '';
2085 
2086  if (isset($objectclasses['posixGroup'])) {
2087  $checks['posixGroup']['IS_MUST_HAVE'] = TRUE;
2088 
2089  /* Depending on mixed groups plugin installation status, we need different schema configurations */
2090  if (class_available('mixedGroup') && isset($objectclasses['posixGroup']['STRUCTURAL'])) {
2091  $checks['posixGroup']['STATUS'] = FALSE;
2092  $checks['posixGroup']['MSG'] = _('You have installed the mixed groups plugin, but your schema configuration does not support this.');
2093  $checks['posixGroup']['INFO'] = _('In order to use mixed groups the objectClass "posixGroup" must be AUXILIARY');
2094  } elseif (!class_available('mixedGroup') && !isset($objectclasses['posixGroup']['STRUCTURAL'])) {
2095  $checks['posixGroup']['STATUS'] = FALSE;
2096  $checks['posixGroup']['MSG'] = _('Your schema is configured to support mixed groups, but this plugin is not present.');
2097  $checks['posixGroup']['INFO'] = _('The objectClass "posixGroup" must be STRUCTURAL');
2098  }
2099  }
2100 
2101  return $checks;
2102 }
2103 
2111 function get_languages($languages_in_own_language = FALSE, $strip_region_tag = FALSE)
2112 {
2113  /* locales in english */
2114  $tmp_english = array(
2115  "ar" => "Arabic",
2116  "ca_ES" => "Catalan",
2117  "cs_CZ" => "Czech",
2118  "de_DE" => "German",
2119  "el_GR" => "Greek",
2120  "en_US" => "English",
2121  "es_CO" => "Colombian Spanish",
2122  "es_ES" => "Spanish",
2123  "es_VE" => "Venezuelan",
2124  "fa_IR" => "Persian",
2125  "fi_FI" => "Finnish",
2126  "fr_FR" => "French",
2127  "it_IT" => "Italian",
2128  "nb" => "Norwegian Bokmål",
2129  "nl_NL" => "Dutch",
2130  "pl_PL" => "Polish",
2131  "pt" => "Portuguese",
2132  "pt_BR" => "Brazilian",
2133  "ru_RU" => "Russian",
2134  "vi_VN" => "Vietnamese",
2135  "sv_SE" => "Swedish",
2136  "zh_CN" => "Chinese",
2137  );
2138 
2139  $ret = array();
2140  if ($languages_in_own_language) {
2141  /* locales in their own language */
2142  $tmp_ownlang = array(
2143  "ar" => "عربية",
2144  "ca_ES" => "Català",
2145  "cs_CZ" => "Česky",
2146  "de_DE" => "Deutsch",
2147  "el_GR" => "ελληνικά",
2148  "en_US" => "English",
2149  "es_CO" => "Español Colombiano",
2150  "es_ES" => "Español",
2151  "es_VE" => "Castellano",
2152  "fa_IR" => "پارسی",
2153  "fi_FI" => "Suomi",
2154  "fr_FR" => "Français",
2155  "it_IT" => "Italiano",
2156  "nb" => "Norsk bokmål",
2157  "nl_NL" => "Nederlands",
2158  "pl_PL" => "Polski",
2159  "pt" => "Portuguese",
2160  "pt_BR" => "Portuguese (Brazil)",
2161  "ru_RU" => "русский язык",
2162  "vi_VN" => "Tiếng Việt",
2163  "sv_SE" => "Svenska",
2164  "zh_CN" => "中文, 汉语, 漢語",
2165  );
2166 
2167  foreach ($tmp_english as $key => $name) {
2168  $label = _($name)." (".$tmp_ownlang[$key].")";
2169  if ($strip_region_tag) {
2170  $ret[preg_replace("/^([^_]*).*$/", "\\1", $key)] = $label;
2171  } else {
2172  $ret[$key] = $label;
2173  }
2174  }
2175  } else {
2176  foreach ($tmp_english as $key => $name) {
2177  if ($strip_region_tag) {
2178  $ret[preg_replace("/^([^_]*).*/", "\\1", $key)] = _($name);
2179  } else {
2180  $ret[$key] = _($name);
2181  }
2182  }
2183  }
2184  return $ret;
2185 }
2186 
2190 function language_is_rtl ($lang)
2191 {
2192  $lang = preg_replace('/\.UTF-8$/', '', $lang);
2193 
2194  if (preg_match('/^fa_/', $lang)) {
2195  return TRUE;
2196  }
2197  return FALSE;
2198 }
2199 
2200 
2211 function get_post($name)
2212 {
2213  if (!isset($_POST[$name])) {
2214  trigger_error("Requested POST value (".$name.") does not exists, you should add a check to prevent this message.");
2215  return FALSE;
2216  }
2217 
2218  return validate($_POST[$name]);
2219 }
2220 
2225 {
2226  global $class_mapping;
2227  if (isset($class_mapping) && is_array($class_mapping)) {
2228  foreach (array_keys($class_mapping) as $class) {
2229  if (preg_match("/^".$cls."$/i", $class)) {
2230  return $class;
2231  }
2232  }
2233  }
2234  return FALSE;
2235 }
2236 
2237 
2252 function change_password ($dn, $password, $hash = "")
2253 {
2254  $userTabs = objects::open($dn, 'user');
2255  $userTab = $userTabs->getBaseObject();
2256  $userTab->userPassword = array(
2257  $hash,
2258  $password,
2259  $password,
2260  $userTab->userPassword,
2261  $userTab->attributesAccess['userPassword']->isLocked()
2262  );
2263  $userTabs->save_object();
2264  $error = $userTabs->save();
2265  if (!empty($error)) {
2266  return $error;
2267  }
2268 
2269  return TRUE;
2270 }
2271 
2272 /* Lock or unlock samba account */
2273 function lock_samba_account($mode, array $attrs)
2274 {
2275  global $config;
2276  if (!isset($attrs['sambaNTPassword'][0])) {
2277  return array();
2278  }
2279  $modify = array('sambaNTPassword' => $attrs['sambaNTPassword'][0]);
2280  if ($config->get_cfg_value("sambaGenLMPassword", "FALSE") == "TRUE") {
2281  $modify['sambaLMPassword'] = $attrs['sambaLMPassword'][0];
2282  } else {
2283  $modify['sambaLMPassword'] = array();
2284  }
2285  foreach ($modify as &$pwd) {
2286  if (is_array($pwd)) {
2287  continue;
2288  }
2289  if ($mode == 'LOCK') {
2290  /* Lock entry */
2291  if (!preg_match('/^\!/', $pwd)) {
2292  $pwd = '!'.$pwd;
2293  }
2294  } else {
2295  /* Unlock entry */
2296  $pwd = preg_replace("/^\!/", "", $pwd);
2297  }
2298  }
2299  unset($pwd);
2300  return $modify;
2301 }
2302 
2303 /* Lock or unlock ssh account */
2304 function lock_ssh_account($mode, array $attrs, &$modify)
2305 {
2306  if (!isset($attrs['sshPublicKey'])) {
2307  return;
2308  }
2309  $modify['sshPublicKey'] = array();
2310  for ($i = 0; $i < $attrs['sshPublicKey']['count']; ++$i) {
2311  if ($mode == 'LOCK') {
2312  $modify['sshPublicKey'][] = preg_replace('/^/', 'disabled-', $attrs['sshPublicKey'][$i]);
2313  } else {
2314  $modify['sshPublicKey'][] = preg_replace('/^disabled-/', '', $attrs['sshPublicKey'][$i]);
2315  }
2316  }
2317 }
2318 
2319 
2332 function getEntryCSN($dn)
2333 {
2334  global $config;
2335  if (empty($dn) || !is_object($config)) {
2336  return '';
2337  }
2338 
2339  /* Get attribute that we should use as serial number */
2340  $attr = $config->get_cfg_value('modificationDetectionAttribute');
2341  if ($attr != '') {
2342  $ldap = $config->get_ldap_link();
2343  $ldap->cat($dn, array($attr));
2344  $csn = $ldap->fetch();
2345  if (isset($csn[$attr][0])) {
2346  return $csn[$attr][0];
2347  }
2348  }
2349  return '';
2350 }
2351 
2361 function send_binary_content($data, $name, $type = "application/octet-stream")
2362 {
2363  header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
2364  header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
2365  header("Cache-Control: no-cache");
2366  header("Pragma: no-cache");
2367  header("Cache-Control: post-check=0, pre-check=0");
2368  header("Content-type: ".$type);
2369 
2370  /* Strip name if it is a complete path */
2371  if (preg_match ("/\//", $name)) {
2372  $name = basename($name);
2373  }
2374 
2375  /* force download dialog */
2376  header('Content-Disposition: attachment; filename="'.$name.'"');
2377 
2378  echo $data;
2379  exit();
2380 }
2381 
2382 
2383 function reverse_html_entities($str, $type = ENT_QUOTES, $charset = "UTF-8")
2384 {
2385  if (is_string($str)) {
2386  return htmlentities($str, $type, $charset);
2387  } elseif (is_array($str)) {
2388  foreach ($str as $name => $value) {
2389  $str[$name] = reverse_html_entities($value, $type, $charset);
2390  }
2391  }
2392  return $str;
2393 }
2394 
2395 
2406 function xmlentities($str)
2407 {
2408  if (is_string($str)) {
2409  return htmlspecialchars($str, ENT_QUOTES);
2410  } elseif (is_array($str)) {
2411  foreach ($str as $name => $value) {
2412  $str[$name] = xmlentities($value);
2413  }
2414  }
2415  return $str;
2416 }
2417 
2421 function get_random_char ()
2422 {
2423  $randno = rand (0, 63);
2424  if ($randno < 12) {
2425  // Digits, '/' and '.'
2426  return chr($randno + 46);
2427  } elseif ($randno < 38) {
2428  // Uppercase
2429  return chr($randno + 53);
2430  } else {
2431  // Lowercase
2432  return chr($randno + 59);
2433  }
2434 }
2435 
2443 function cred_decrypt($input, $password)
2444 {
2445  /************************* Inspired by Crypt/CBC.pm *******************************/
2446  $input = pack('H*', $input);
2447  if (substr($input, 0, 8) != 'Salted__') {
2448  throw new FusionDirectoryException("Invalid hash header: expected 'Salted__', found '".substr($input, 0, 8)."'");
2449  }
2450  $salt = substr($input, 8, 8);
2451  $input = substr($input, 16);
2452 
2453  $key_len = 32;
2454  $iv_len = openssl_cipher_iv_length('aes-256-cbc');
2455 
2456  $data = '';
2457  $d = '';
2458  while (strlen($data) < $key_len + $iv_len) {
2459  $d = md5($d . $password . $salt, TRUE);
2460  $data .= $d;
2461  }
2462  $key = substr($data, 0, $key_len);
2463  $iv = substr($data, $key_len, $iv_len);
2464 
2465  return openssl_decrypt($input, 'aes-256-cbc', $key, OPENSSL_RAW_DATA, $iv);
2466 }
2467 
2468 
2469 function get_object_info()
2470 {
2471  return session::get('objectinfo');
2472 }
2473 
2474 
2475 function set_object_info($str = "")
2476 {
2477  session::set('objectinfo', $str);
2478 }
2479 
2489 function isIpInNet($ip, $net, $mask)
2490 {
2491  // Move to long ints
2492  $ip = ip2long($ip);
2493  $net = ip2long($net);
2494  $mask = ip2long($mask);
2495 
2496  // Mask given IP with mask. If it returns "net", we're in...
2497  return (($ip & $mask) == $net);
2498 }
2499 
2503 function expandIPv6 ($ip)
2504 {
2505  $hex = unpack('H*hex', inet_pton($ip));
2506  $ip = substr(preg_replace('/([A-f0-9]{4})/', "$1:", $hex['hex']), 0, -1);
2507 
2508  return $ip;
2509 }
2510 
2511 /* Mark the occurance of a string with a span */
2512 function mark($needle, $haystack)
2513 {
2514  $result = '';
2515 
2516  while (preg_match('/^(.*)('.preg_quote($needle).')(.*)$/i', $haystack, $matches)) {
2517  $result .= $matches[1].'<span class="mark">'.$matches[2].'</span>';
2518  $haystack = $matches[3];
2519  }
2520 
2521  return $result.$haystack;
2522 }
2523 
2524 function reset_errors()
2525 {
2526  session::set('errors', '');
2527  session::set('errorsAlreadyPosted', array());
2528  session::set('LastError', '');
2529 }
2530 
2531 function load_all_classes()
2532 {
2533  global $BASE_DIR, $class_list, $class_mapping;
2534  /* Initially load all classes */
2535  $class_list = get_declared_classes();
2536  foreach ($class_mapping as $class => $path) {
2537  if (!in_array($class, $class_list)) {
2538  if (is_readable("$BASE_DIR/$path")) {
2539  require_once("$BASE_DIR/$path");
2540  } else {
2541  msg_dialog::display(_('Fatal error'),
2542  sprintf(_("Cannot locate file '%s' - please run '%s' to fix this"),
2543  "$BASE_DIR/$path", '<b>fusiondirectory-setup</b>'), FATAL_ERROR_DIALOG);
2544  exit;
2545  }
2546  }
2547  }
2548 }
2549 
2550 function initLanguage($lang = NULL)
2551 {
2552  global $BASE_DIR;
2553  if ($lang === NULL) {
2554  $lang = get_browser_language();
2555  }
2556 
2557  putenv('LANGUAGE=');
2558  putenv("LANG=$lang");
2559  setlocale(LC_ALL, $lang);
2560  $GLOBALS['t_language'] = $lang;
2561  $GLOBALS['t_gettext_message_dir'] = $BASE_DIR.'/locale/';
2562 
2563  /* Set the text domain as 'fusiondirectory' */
2564  $domain = 'fusiondirectory';
2565  bindtextdomain($domain, LOCALE_DIR);
2566  textdomain($domain);
2567  if ($_SERVER['REQUEST_METHOD'] != 'POST') {
2568  @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__, $lang, 'Setting language to');
2569  }
2570 
2571  $ret = FALSE;
2572 
2573  /* Reset plist cache if language changed */
2574  if ((!session::global_is_set('lang')) || (session::global_get('lang') != $lang)) {
2575  $ret = TRUE;
2576  if (session::global_is_set('plist')) {
2577  if ($_SERVER['REQUEST_METHOD'] != 'POST') {
2578  @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__, session::global_get('lang'), 'Plist already loaded with language');
2579  }
2580  session::global_un_set('plist');
2581  session::global_set('lang', $lang);
2582  load_plist();
2583  }
2584  }
2585 
2586  session::global_set('lang', $lang);
2587  return $ret;
2588 }
2589 
2590 if (!function_exists('ldap_escape')) {
2591  /* This bloc is for PHP<5.6 */
2592  define('LDAP_ESCAPE_FILTER', 0x01);
2593  define('LDAP_ESCAPE_DN', 0x02);
2594 
2602  function ldap_escape($subject, $ignore = '', $flags = 0)
2603  {
2604  static $charMaps = array(
2605  LDAP_ESCAPE_FILTER => array('\\', '*', '(', ')', "\x00"),
2606  LDAP_ESCAPE_DN => array('\\', ',', '=', '+', '<', '>', ';', '"', '#'),
2607  );
2608 
2609  // Pre-process the char maps on first call
2610  if (!isset($charMaps[0])) {
2611  $charMaps[0] = array();
2612  for ($i = 0; $i < 256; $i++) {
2613  $charMaps[0][chr($i)] = sprintf('\\%02x', $i);
2614  }
2615 
2616  for ($i = 0, $l = count($charMaps[LDAP_ESCAPE_FILTER]); $i < $l; $i++) {
2617  $chr = $charMaps[LDAP_ESCAPE_FILTER][$i];
2618  unset($charMaps[LDAP_ESCAPE_FILTER][$i]);
2619  $charMaps[LDAP_ESCAPE_FILTER][$chr] = $charMaps[0][$chr];
2620  }
2621 
2622  for ($i = 0, $l = count($charMaps[LDAP_ESCAPE_DN]); $i < $l; $i++) {
2623  $chr = $charMaps[LDAP_ESCAPE_DN][$i];
2624  unset($charMaps[LDAP_ESCAPE_DN][$i]);
2625  $charMaps[LDAP_ESCAPE_DN][$chr] = $charMaps[0][$chr];
2626  }
2627  }
2628 
2629  // Create the base char map to escape
2630  $flags = (int)$flags;
2631  $charMap = array();
2632  if ($flags & LDAP_ESCAPE_FILTER) {
2633  $charMap += $charMaps[LDAP_ESCAPE_FILTER];
2634  }
2635  if ($flags & LDAP_ESCAPE_DN) {
2636  $charMap += $charMaps[LDAP_ESCAPE_DN];
2637  }
2638  if (!$charMap) {
2639  $charMap = $charMaps[0];
2640  }
2641 
2642  // Remove any chars to ignore from the list
2643  $ignore = (string)$ignore;
2644  for ($i = 0, $l = strlen($ignore); $i < $l; $i++) {
2645  unset($charMap[$ignore[$i]]);
2646  }
2647 
2648  // Do the main replacement
2649  $result = strtr($subject, $charMap);
2650 
2651  // Encode leading/trailing spaces if LDAP_ESCAPE_DN is passed
2652  if ($flags & LDAP_ESCAPE_DN) {
2653  if ($result[0] === ' ') {
2654  $result = '\\20' . substr($result, 1);
2655  }
2656  if ($result[strlen($result) - 1] === ' ') {
2657  $result = substr($result, 0, -1) . '\\20';
2658  }
2659  }
2660 
2661  return $result;
2662  }
2663 }
2664 
2665 function ldap_escape_f($str, $ignore = '')
2666 {
2667  return ldap_escape($str, $ignore, LDAP_ESCAPE_FILTER);
2668 }
2669 
2670 function ldap_escape_dn($str, $ignore = '')
2671 {
2672  return ldap_escape($str, $ignore, LDAP_ESCAPE_DN);
2673 }
2674 
2675 function mail_utf8($to, $from_user, $from_email, $subject, $message, $type = 'plain')
2676 {
2677  $subject = "=?UTF-8?B?".base64_encode($subject)."?=";
2678  if ($from_user) {
2679  $from_user = "=?UTF-8?B?".base64_encode($from_user)."?=";
2680  $headers = "From: $from_user <$from_email>\r\n";
2681  $headers .= "Reply-To: $from_user <$from_email>\r\n";
2682  } else {
2683  $headers = "From: <$from_email>\r\n";
2684  $headers .= "Reply-To: <$from_email>\r\n";
2685  }
2686  $headers .= "MIME-Version: 1.0" . "\r\n" .
2687  "Content-type: text/$type; charset=UTF-8" . "\r\n";
2688 
2689  $additional_parameters = "-f".$from_email;
2690 
2691  return mail($to, $subject, $message, $headers, $additional_parameters);
2692 }
2693 
2694 /* Calls fopen, gives errors as an array if any, file handle if successful */
2695 function fopenWithErrorHandling()
2696 {
2697  $args = func_get_args();
2698  $errors = array();
2699  set_error_handler(
2700  function ($errno, $errstr, $errfile, $errline, $errcontext) use (&$errors)
2701  {
2702  $errors[] = $errstr;
2703  }
2704  );
2705  $fh = @call_user_func_array('fopen', $args);
2706  restore_error_handler();
2707  if ($fh !== FALSE) {
2708  return $fh;
2709  }
2710  return $errors;
2711 }
2712 ?>
static backButton()
Text for a back button.
const CACHE_DIR
Global cache dir.
Definition: variables.inc:55
cred_decrypt($input, $password)
Decrypt a string with RIJNDAEL_128.
Definition: functions.inc:2443
get_random_char()
Returns a random char.
Definition: functions.inc:2421
const FD_VERSION
FusionDirectory Version.
rmdirRecursive($path, $followLinks=FALSE)
Recursively delete a path in the file system.
Definition: functions.inc:1738
const CLASS_CACHE
name of the class.cache file
Definition: variables.inc:85
eval_sizelimit()
Handle sizelimit dialog related posts.
Definition: functions.inc:908
in_array_ics($value, array $items)
Check if a value exists in an array (case-insensitive)
Definition: functions.inc:1677
get_lock($object)
Get a lock for a specific object.
Definition: functions.inc:764
normalize_netmask($netmask)
Put netmask in n.n.n.n format.
Definition: functions.inc:1402
array_differs_recursive($src, $dst)
Determine if two arrays are different using recursion for sublevels.
Definition: functions.inc:1960
get_ou($name)
Get the OU of a certain RDN.
Definition: functions.inc:1020
compare_revision($revision_file, $revision)
Compare the revision file.
Definition: functions.inc:1879
check_sizelimit()
Show sizelimit configuration dialog.
Definition: functions.inc:865
This class contains all function to manage ldap multiplexer.
get_browser_language()
Determine which language to show to the user.
Definition: functions.inc:265
gen_uids($rule, $attributes)
Generate a list of uid proposals based on a rule.
Definition: functions.inc:1510
del_user_locks($userdn)
Remove all locks owned by a specific userdn.
Definition: functions.inc:738
get_languages($languages_in_own_language=FALSE, $strip_region_tag=FALSE)
Get the language for the user connecting.
Definition: functions.inc:2111
scan_directory($path, $sort_desc=FALSE)
Get directory content information.
Definition: functions.inc:1765
send_binary_content($data, $name, $type="application/octet-stream")
Initialize a file download with given content, name and data type.
Definition: functions.inc:2361
This class contains all the function needed to make list of plugin and manage them.
static ldaperror($error, $dn= '', $type=0, $plugin= '')
Display LDAP error.
& get_userinfo()
Return the current userinfo object.
Definition: functions.inc:941
load_plist($ldap_available=TRUE)
Loads plist and load it in config object.
Definition: functions.inc:160
del_lock($object)
Remove a lock for object(s)
Definition: functions.inc:689
__fusiondirectory_autoload($class_name)
Does autoloading for classes used in FusionDirectory.
Definition: functions.inc:86
get_template_path($filename= '', $plugin=FALSE, $path= '')
Return themed path for specified base file.
Definition: functions.inc:315
ldap_get_user($username)
Get user from LDAP directory.
Definition: functions.inc:494
fusiondirectory_log($message)
Generate a system log info.
Definition: functions.inc:429
array_merge_unique($ar1, $ar2)
Merge to array but remove duplicate entries (case-insensitive)
Definition: functions.inc:412
get_correct_class_name($cls)
Return class name in correct case.
Definition: functions.inc:2224
static set($name, $value)
Set a value in a session.
get_base_from_people($dn)
Return a base from a given user DN.
Definition: functions.inc:1130
ldap_init($server, $base, $binddn= '', $pass= '')
Initialize a LDAP connection.
Definition: functions.inc:464
static & get($name)
Accessor of a session.
_recurse_gen_uids($rule, $variables)
Recursion helper for gen_uids()
Definition: functions.inc:1476
& get_smarty()
Get global smarty object.
Definition: functions.inc:953
static global_un_set($name)
Unset a session.
static global_set($name, $value)
Set a value in a session.
isIpInNet($ip, $net, $mask)
Test if an ip is the network range.
Definition: functions.inc:2489
ldap_login_user($username, $password)
Verify user login against LDAP directory.
Definition: functions.inc:566
getEntryCSN($dn)
Get the Change Sequence Number of a certain DN.
Definition: functions.inc:2332
netmask_to_bits($netmask)
Return the number of set bits in the netmask.
Definition: functions.inc:1452
language_is_rtl($lang)
Returns TRUE if $lang is a right to left language ($lang should match /.._..(.UTF-8)?/)
Definition: functions.inc:2190
static parseMask($mask, array $attrs)
Parse a mask (without surrounding %) using $attrs attributes, apply modifiers and returns an array co...
check_schema($cfg)
Check if LDAP schema matches the requirements.
Definition: functions.inc:1999
Parent class for all exceptions thrown in FusionDirectory.
to_string($value)
Return a string/HTML representation of an array.
Definition: functions.inc:1271
dn2base($dn, $ou=NULL)
Return the base of a given DN.
Definition: functions.inc:1314
change_password($dn, $password, $hash="")
Change the password of a given DN.
Definition: functions.inc:2252
This class contains all ldap function needed to make ldap operations easy.
Definition: class_ldap.inc:34
create_revision($revision_file, $revision)
Create the revision file.
Definition: functions.inc:1851
Class userinfo This class contains all informations and functions about user.
generate_alphabet($count=10)
Generate a clickable alphabet.
Definition: functions.inc:1684
rewrite($s)
Function to rewrite some problematic characters.
Definition: functions.inc:1294
gen_locked_message($locks, $dn, $allow_readonly=FALSE)
Generate a lock message.
Definition: functions.inc:1189
xmlentities($str)
Encode special string characters.
Definition: functions.inc:2406
validate($string)
Removes malicious characters from a (POST) string.
Definition: functions.inc:1722
get_locks($objects, $allow_readonly=FALSE)
Get locks for objects.
Definition: functions.inc:801
DEBUG($level, $line, $function, $file, $data, $info= '')
Debug level action.
Definition: functions.inc:219
array_differs($src, $dst)
Determine if two arrays are different.
Definition: functions.inc:1941
initLanguage($lang=NULL)
Definition: functions.inc:2550
strict_uid_mode()
Check if strict naming rules are configured.
Definition: functions.inc:1155
array_key_ics($ikey, array $items)
Lookup a key in an array case-insensitive.
Definition: functions.inc:1920
print_header($image, $headline, $info= '')
Print plugin HTML header.
Definition: functions.inc:1368
static fromString($string, $useException=TRUE)
Convert from LDAP GeneralizedTime formatted string to DateTime object.
get_people_ou()
Get the OU for users.
Definition: functions.inc:1114
check_command($cmdline)
Check if a given command exists and is executable.
Definition: functions.inc:1340
const LOCALE_DIR
Global locale cache dir.
Definition: variables.inc:60
get_post($name)
Returns contents of the given POST variable and check magic quotes settings.
Definition: functions.inc:2211
static global_get($name)
Accessor of a session var.
expandIPv6($ip)
Expands an IP v6.
Definition: functions.inc:2503
make_seed()
Create seed with microseconds.
Definition: functions.inc:190
clean_smarty_compile_dir($directory)
Clean the smarty compile dir.
Definition: functions.inc:1805
normalizeLdap($input)
Escape all LDAP filter relevant characters.
Definition: functions.inc:1988
static display($s_title, $s_message, $i_type=INFO_DIALOG)
Display a message dialog.
static & global_get_ref($name)
Accessor of a session var by reference.
convert_department_dn($dn, $base=NULL)
Convert a department DN to a sub-directory style list.
Definition: functions.inc:978
to_byte($value)
Convert various data sizes to bytes.
Definition: functions.inc:1610
plugin_available($plugin)
Check if plugin is available.
Definition: functions.inc:146
static open($dn, $type)
Create the tab object for the given dn.
static toString($date, $setToUTC=TRUE)
Convert from DateTime object to LDAP GeneralizedTime formatted string.
array_remove_entries_ics(array $needles, array $haystack)
Remove multiple entries from an array (case-insensitive)
Definition: functions.inc:394
static global_is_set($name)
Check if a session is defined.
array_remove_entries(array $needles, array $haystack)
Remove multiple entries from an array.
Definition: functions.inc:378
static is_set($name)
Check if the name of the session is set.
back_to_main()
Generate HTML for the 'Back' button.
Definition: functions.inc:1389
add_lock($object, $user)
Add a lock for object(s)
Definition: functions.inc:619
print_sizelimit_warning()
Print a sizelimit warning.
Definition: functions.inc:890
humanReadableSize($bytes, $precision=2)
Convert a size in bytes to a human readable version.
Definition: functions.inc:1643
class_available($name)
Checks if a class is available.
Definition: functions.inc:130
static is_id($id)
Check if the given argument is an id.