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 
200 function DEBUG($level, $line, $function, $file, $data, $info = '')
201 {
202  static $first = TRUE;
203  if (($_SERVER['REQUEST_METHOD'] == 'POST') && preg_match('/index.php$/', $_SERVER['REQUEST_URI'])) {
204  return;
205  }
206  if (session::global_get('DEBUGLEVEL') & $level) {
207  if ($first) {
208  echo '<div id="debug-handling" class="notice">'.
209  '<img src="geticon.php?context=status&amp;icon=dialog-information&amp;size=22" alt="info icon" style="vertical-align:middle;margin-right:.2em;"/>'.
210  'There is some debug output '.
211  '<button onClick="javascript:$$(\'div.debug_div\').each(function (a) { a.toggle(); });">Toggle</button>'.
212  '</div>';
213  $first = FALSE;
214  }
215  $output = "DEBUG[$level] ";
216  if ($function != '') {
217  $output .= "($file:$function():$line) - $info: ";
218  } else {
219  $output .= "($file:$line) - $info: ";
220  }
221  echo '<div class="debug_div">';
222  echo $output;
223  if (is_array($data)) {
224  print_a($data);
225  } else {
226  echo "'$data'";
227  }
228  echo "</div>\n";
229  }
230 }
231 
232 
247 {
248  /* Try to use users primary language */
249  global $config;
250  $ui = get_userinfo();
251  if (isset($ui) && ($ui !== NULL) && ($ui->language != '')) {
252  return $ui->language.'.UTF-8';
253  }
254 
255  /* Check for global language settings in configuration */
256  if (isset($config) && ($config->get_cfg_value('language') != '')) {
257  $lang = $config->get_cfg_value('language');
258  if (!preg_match('/utf/i', $lang)) {
259  $lang .= '.UTF-8';
260  }
261  return $lang;
262  }
263 
264  /* Load supported languages */
265  $gosa_languages = get_languages();
266 
267  /* Move supported languages to flat list */
268  $langs = array();
269  foreach (array_keys($gosa_languages) as $lang) {
270  $langs[] = $lang.'.UTF-8';
271  }
272  /* Return gettext based string */
273  return al2gt($langs, 'text/html');
274 }
275 
296 function get_template_path($filename = '', $plugin = FALSE, $path = '')
297 {
298  global $config, $BASE_DIR;
299  $default_theme = 'breezy';
300 
301  /* Set theme */
302  if (isset ($config)) {
303  $theme = $config->get_cfg_value('theme', $default_theme);
304  } else {
305  $theme = $default_theme;
306  }
307 
308  /* Return path for empty filename */
309  if ($filename == '') {
310  return "themes/$theme/";
311  }
312 
313  /* Return plugin dir or root directory? */
314  if ($plugin) {
315  if ($path == '') {
316  $path = session::global_get('plugin_dir');
317  $nf = preg_replace('!^'.$BASE_DIR.'/!', '', preg_replace('/^\.\.\//', '', $path));
318  } else {
319  $nf = preg_replace('!^'.$BASE_DIR.'/!', '', $path);
320  }
321  $paths = array(
322  "$BASE_DIR/ihtml/themes/$theme/$nf/$filename",
323  "$BASE_DIR/ihtml/themes/$default_theme/$nf/$filename",
324  "$BASE_DIR/ihtml/themes/default/$nf/$filename",
325  $path."/$filename"
326  );
327  } else {
328  $paths = array(
329  "themes/$theme/$filename",
330  "$BASE_DIR/ihtml/themes/$theme/$filename",
331  "themes/$default_theme/$filename",
332  "$BASE_DIR/ihtml/themes/$default_theme/$filename",
333  "themes/default/$filename",
334  "$BASE_DIR/ihtml/themes/default/$filename",
335  $filename
336  );
337  }
338 
339  foreach ($paths as $path) {
340  if (file_exists($path)) {
341  return $path;
342  }
343  }
344 
345  return end($paths);
346 }
347 
348 
359 function array_remove_entries(array $needles, array $haystack)
360 {
361  return array_values(array_diff($haystack, $needles));
362 }
363 
364 
375 function array_remove_entries_ics(array $needles, array $haystack)
376 {
377  // strcasecmp will work, because we only compare ASCII values here
378  return array_values(array_udiff($haystack, $needles, 'strcasecmp'));
379 }
380 
393 function array_merge_unique($ar1, $ar2)
394 {
395  if (!is_array($ar1) || !is_array($ar2)) {
396  trigger_error('Specified parameter(s) are not valid arrays.');
397  } else {
398  return array_values(array_unique(array_merge($ar1, $ar2)));
399  }
400 }
401 
402 
410 function fusiondirectory_log ($message)
411 {
412  global $ui;
413 
414  /* Preset to something reasonable */
415  $username = '[unauthenticated]';
416 
417  /* Replace username if object is present */
418  if (isset($ui)) {
419  if ($ui->uid != '') {
420  $username = '['.$ui->uid.']';
421  } else {
422  $username = '[unknown]';
423  }
424  }
425 
426  syslog(LOG_INFO, "FusionDirectory $username: $message");
427 }
428 
429 
445 function ldap_init ($server, $base, $binddn = '', $pass = '')
446 {
447  global $config;
448 
449  $ldap = new LDAP ($binddn, $pass, $server,
450  isset($config->current['LDAPFOLLOWREFERRALS']) && $config->current['LDAPFOLLOWREFERRALS'] == 'TRUE',
451  isset($config->current['LDAPTLS']) && $config->current['LDAPTLS'] == 'TRUE');
452 
453  /* Sadly we've no proper return values here. Use the error message instead. */
454  if (!$ldap->success()) {
455  msg_dialog::display(_('Fatal error'),
456  sprintf(_("FATAL: Error when connecting the LDAP. Server said '%s'."), $ldap->get_error()),
457  FATAL_ERROR_DIALOG);
458  exit();
459  }
460 
461  /* Preset connection base to $base and return to caller */
462  $ldap->cd ($base);
463  return $ldap;
464 }
465 
475 function ldap_get_user ($username)
476 {
477  global $config;
478 
479  /* look through the entire ldap */
480  $ldap = $config->get_ldap_link();
481  if (!$ldap->success()) {
482  msg_dialog::display(_('LDAP error'),
483  msgPool::ldaperror($ldap->get_error(), '', LDAP_AUTH).'<br/><br/>'.session::get('errors'),
484  FATAL_ERROR_DIALOG);
485  exit();
486  }
487 
488  $allowed_attributes = array('uid','mail');
489  $verify_attr = array();
490  $tmp = explode(',', $config->get_cfg_value('loginAttribute'));
491  foreach ($tmp as $attr) {
492  if (in_array($attr, $allowed_attributes)) {
493  $verify_attr[] = $attr;
494  }
495  }
496 
497  if (count($verify_attr) == 0) {
498  $verify_attr = array('uid');
499  }
500  $tmp = $verify_attr;
501  $tmp[] = 'uid';
502  $filter = '';
503  foreach ($verify_attr as $attr) {
504  $filter .= '('.$attr.'='.$username.')';
505  }
506  $filter = '(&(|'.$filter.')(objectClass=inetOrgPerson))';
507  $ldap->cd($config->current['BASE']);
508  $ldap->search($filter, $tmp);
509 
510  /* get results, only a count of 1 is valid */
511  if ($ldap->count() == 0) {
512  /* user not found */
513  return FALSE;
514  } elseif ($ldap->count() != 1) {
515  /* found more than one matching id */
516  return _('Login (uid) is not unique inside the LDAP tree. Please contact your administrator.');
517  }
518 
519  /* LDAP schema is not case sensitive. Perform additional check. */
520  $attrs = $ldap->fetch();
521  $success = FALSE;
522  foreach ($verify_attr as $attr) {
523  if (isset($attrs[$attr][0]) && $attrs[$attr][0] == $username) {
524  $success = TRUE;
525  }
526  }
527  $ldap->disconnect();
528  if (!$success) {
529  return FALSE;
530  }
531 
532  return new userinfo($attrs['dn']);
533 }
534 
547 function ldap_login_user ($username, $password)
548 {
549  global $config;
550 
551  $ui = ldap_get_user($username);
552 
553  if ($ui === FALSE) {
554  return NULL;
555  } elseif (is_string($ui)) {
556  msg_dialog::display(_('Internal error'), $ui, FATAL_ERROR_DIALOG);
557  return NULL;
558  }
559 
560  /* password check, bind as user with supplied password */
561  $ldapObj = new LDAP($ui->dn, $password, $config->current['SERVER'],
562  isset($config->current['LDAPFOLLOWREFERRALS']) &&
563  $config->current['LDAPFOLLOWREFERRALS'] == 'TRUE',
564  isset($config->current['LDAPTLS'])
565  && $config->current['LDAPTLS'] == 'TRUE'
566  );
567  $ldap = new ldapMultiplexer($ldapObj);
568  if (!$ldap->success()) {
569  return NULL;
570  }
571  if (class_available('ppolicyAccount')) {
572  $ldap->cd($config->current['BASE']);
573  $ldap->search('(objectClass=*)', array(), 'one');
574  if (!$ldap->success()) {
576  _('Authentication error'),
577  _('It seems your user password has expired. Please use <a href="recovery.php">password recovery</a> to change it.'),
578  ERROR_DIALOG
579  );
580  return NULL;
581  }
582  }
583 
584  /* Username is set, load subtreeACL's now */
585  $ui->loadACL();
586 
587  return $ui;
588 }
589 
600 function add_lock($object, $user)
601 {
602  global $config;
603 
604  /* Remember which entries were opened as read only, because we
605  don't need to remove any locks for them later.
606  */
607  if (!session::global_is_set('LOCK_CACHE')) {
608  session::global_set('LOCK_CACHE', array(''));
609  }
610  if (is_array($object)) {
611  foreach ($object as $obj) {
612  add_lock($obj, $user);
613  }
614  return;
615  }
616 
617  $cache = &session::global_get_ref('LOCK_CACHE');
618  if (isset($_POST['open_readonly'])) {
619  $cache['READ_ONLY'][$object] = TRUE;
620  return;
621  }
622  if (isset($cache['READ_ONLY'][$object])) {
623  unset($cache['READ_ONLY'][$object]);
624  }
625 
626  /* Just a sanity check... */
627  if ($object == '' || $user == '') {
628  msg_dialog::display(_('Internal error'), _('Error while adding a lock. Contact the developers!'), ERROR_DIALOG);
629  return;
630  }
631 
632  /* Check for existing entries in lock area */
633  $ldap = $config->get_ldap_link();
634  $ldap->cd(get_ou('lockRDN').get_ou('fusiondirectoryRDN').$config->current['BASE']);
635  $ldap->search('(&(objectClass=fdLockEntry)(fdUserDn='.ldap_escape_f($user).')(fdObjectDn='.base64_encode($object).'))',
636  array('fdUserDn'));
637  if (!$ldap->success()) {
638  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);
639  return;
640  }
641 
642  /* Add lock if none present */
643  if ($ldap->count() == 0) {
644  $attrs = array();
645  $name = md5($object);
646  $ldap->cd('cn='.$name.','.get_ou('lockRDN').get_ou('fusiondirectoryRDN').$config->current['BASE']);
647  $attrs = array(
648  'objectClass' => 'fdLockEntry',
649  'fdUserDn' => $user,
650  'fdObjectDn' => base64_encode($object),
651  'cn' => $name,
652  'fdLockTimestamp' => LdapGeneralizedTime::toString(new DateTime('now')),
653  );
654  $ldap->add($attrs);
655  if (!$ldap->success()) {
656  msg_dialog::display(_('LDAP error'), msgPool::ldaperror($ldap->get_error(), "cn=$name,".get_ou('lockRDN').get_ou('fusiondirectoryRDN').$config->current['BASE'], 0), LDAP_ERROR);
657  return;
658  }
659  }
660 }
661 
662 
670 function del_lock ($object)
671 {
672  global $config;
673 
674  if (is_array($object)) {
675  foreach ($object as $obj) {
676  del_lock($obj);
677  }
678  return;
679  }
680 
681  /* Sanity check */
682  if ($object == '') {
683  return;
684  }
685 
686  /* If this object was opened in read only mode then
687  skip removing the lock entry, there wasn't any lock created.
688  */
689  if (session::global_is_set('LOCK_CACHE')) {
690  $cache = &session::global_get_ref('LOCK_CACHE');
691  if (isset($cache['READ_ONLY'][$object])) {
692  unset($cache['READ_ONLY'][$object]);
693  return;
694  }
695  }
696 
697  /* Check for existance and remove the entry */
698  $ldap = $config->get_ldap_link();
699  $ldap->cd(get_ou('lockRDN').get_ou('fusiondirectoryRDN').$config->current['BASE']);
700  $ldap->search('(&(objectClass=fdLockEntry)(fdObjectDn='.base64_encode($object).'))', array('fdObjectDn'));
701  $attrs = $ldap->fetch();
702  if (!$ldap->success()) {
703  msg_dialog::display(_('LDAP error'), msgPool::ldaperror($ldap->get_error(), $ldap->getDN(), LDAP_DEL, ERROR_DIALOG));
704  return;
705  } elseif (!empty($attrs['dn'])) {
706  $ldap->rmdir($attrs['dn']);
707  }
708 }
709 
710 
719 function del_user_locks($userdn)
720 {
721  global $config;
722 
723  /* Get LDAP ressources */
724  $ldap = $config->get_ldap_link();
725  $ldap->cd(get_ou('lockRDN').get_ou('fusiondirectoryRDN').$config->current['BASE']);
726 
727  /* Remove all objects of this user, drop errors silently in this case. */
728  $ldap->search('(&(objectClass=fdLockEntry)(fdUserDn='.ldap_escape_f($userdn).'))', array('fdUserDn'));
729  while ($attrs = $ldap->fetch()) {
730  $ldap->rmdir($attrs['dn']);
731  }
732 }
733 
734 
745 function get_lock($object)
746 {
747  /* Sanity check */
748  if ($object == '') {
749  msg_dialog::display(_('Internal error'), _('Error while adding a lock. Contact the developers!'), ERROR_DIALOG);
750  return FALSE;
751  }
752 
753  /* Allow readonly access, the plugin constructor will restrict the acls */
754  if (isset($_POST['open_readonly'])) {
755  return '';
756  }
757 
758  $locks = get_locks($object);
759  if ($locks === FALSE) {
760  return FALSE;
761  } elseif (empty($locks)) {
762  return '';
763  } else {
764  return $locks[0]['user'];
765  }
766 }
767 
768 
782 function get_locks($objects, $allow_readonly = FALSE)
783 {
784  global $config;
785 
786  if (is_array($objects) && count($objects == 1)) {
787  $objects = reset($objects);
788  }
789  if (is_array($objects)) {
790  if ($allow_readonly) {
791  trigger_error('Read only is not possible for several objects');
792  }
793  $filter = '(&(objectClass=fdLockEntry)(|';
794  foreach ($objects as $obj) {
795  $filter .= '(fdObjectDn='.base64_encode($obj).')';
796  }
797  $filter .= '))';
798  } else {
799  if ($allow_readonly && isset($_POST['open_readonly'])) {
800  /* If readonly is allowed and asked and there is only one object, bypass lock detection */
801  return array();
802  }
803  $filter = '(&(objectClass=fdLockEntry)(fdObjectDn='.base64_encode($objects).'))';
804  }
805 
806  /* Get LDAP link, check for presence of the lock entry */
807  $ldap = $config->get_ldap_link();
808  $ldap->cd(get_ou('lockRDN').get_ou('fusiondirectoryRDN').$config->current['BASE']);
809  $ldap->search($filter, array('fdUserDn','fdObjectDn', 'fdLockTimestamp'));
810  if (!$ldap->success()) {
811  msg_dialog::display(_('LDAP error'), msgPool::ldaperror($ldap->get_error(), '', LDAP_SEARCH), LDAP_ERROR);
812  return FALSE;
813  }
814 
815  $locks = array();
816  while ($attrs = $ldap->fetch()) {
817  $locks[] = array(
818  'dn' => $attrs['dn'],
819  'object' => base64_decode($attrs['fdObjectDn'][0]),
820  'user' => $attrs['fdUserDn'][0],
821  'timestamp' => LdapGeneralizedTime::fromString($attrs['fdLockTimestamp'][0]),
822  );
823  }
824 
825  if (!is_array($objects) && (count($locks) > 1)) {
826  /* Hmm. We're removing broken LDAP information here and issue a warning. */
827  msg_dialog::display(_('Warning'), _('Found multiple locks for object to be locked. This should not happen - cleaning up multiple references.'), WARNING_DIALOG);
828 
829  /* Clean up these references now... */
830  foreach ($locks as $lock) {
831  $ldap->rmdir($lock['dn']);
832  }
833 
834  return FALSE;
835  }
836 
837  return $locks;
838 }
839 
846 function check_sizelimit()
847 {
848  /* Ignore dialog? */
849  if (session::global_is_set('size_ignore') && session::global_get('size_ignore')) {
850  return '';
851  }
852 
853  /* Eventually show dialog */
854  if (session::is_set('limit_exceeded') && session::get('limit_exceeded')) {
855  $smarty = get_smarty();
856  $smarty->assign('warning', sprintf(_('The size limit of %d entries is exceed!'),
857  session::global_get('size_limit')));
858  $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).'"/>'));
859  return $smarty->fetch(get_template_path('sizelimit.tpl'));
860  }
861 
862  return '';
863 }
864 
872 {
873  if (session::global_is_set('size_limit') && session::global_get('size_limit') >= 10000000 ||
874  (session::is_set('limit_exceeded') && session::get('limit_exceeded'))) {
875  $config = '<input type="submit" name="edit_sizelimit" value="'._('Configure').'"/>';
876  } else {
877  $config = '';
878  }
879  if (session::is_set('limit_exceeded') && session::get('limit_exceeded')) {
880  return '('._('incomplete').") $config";
881  }
882  return '';
883 }
884 
885 
889 function eval_sizelimit()
890 {
891  if (isset($_POST['set_size_action']) && isset($_POST['action'])) {
892  switch($_POST['action']) {
893  case 'newlimit':
894  if (isset($_POST['new_limit']) && tests::is_id($_POST['new_limit'])) {
895  session::global_set('size_limit', validate($_POST['new_limit']));
896  session::set('size_ignore', FALSE);
897  }
898  break;
899  case 'ignore':
900  session::global_set('size_limit', 0);
901  session::global_set('size_ignore', TRUE);
902  break;
903  case 'limited':
904  session::global_set('size_ignore', TRUE);
905  break;
906  default:
907  break;
908  }
909  }
910 
911  /* Allow fallback to dialog */
912  if (isset($_POST['edit_sizelimit'])) {
913  session::global_set('size_ignore', FALSE);
914  }
915 }
916 
922 function &get_userinfo()
923 {
924  global $ui;
925 
926  return $ui;
927 }
928 
934 function &get_smarty()
935 {
936  global $smarty;
937 
938  return $smarty;
939 }
940 
959 function convert_department_dn($dn, $base = NULL)
960 {
961  global $config;
962 
963  if ($base == NULL) {
964  $base = $config->current['BASE'];
965  }
966 
967  /* Build a sub-directory style list of the tree level
968  specified in $dn */
969  $dn = preg_replace('/'.preg_quote($base, '/')."$/i", '', $dn);
970  if (empty($dn)) {
971  return '/';
972  }
973 
974  $dep = '';
975  foreach (explode(',', $dn) as $rdn) {
976  $dep = preg_replace("/^[^=]+=/", '', $rdn).'/'.$dep;
977  }
978 
979  /* Return and remove accidently trailing slashes */
980  return trim($dep, '/');
981 }
982 
1001 function get_ou($name)
1002 {
1003  global $config;
1004 
1005  $map = array(
1006  'fusiondirectoryRDN' => 'ou=fusiondirectory,',
1007  'lockRDN' => 'ou=locks,',
1008  'recoveryTokenRDN' => 'ou=recovery,',
1009  'reminderTokenRDN' => 'ou=reminder,',
1010  'roleRDN' => 'ou=roles,',
1011  'ogroupRDN' => 'ou=groups,',
1012  'applicationRDN' => 'ou=apps,',
1013  'systemRDN' => 'ou=systems,',
1014  'serverRDN' => 'ou=servers,ou=systems,',
1015  'terminalRDN' => 'ou=terminals,ou=systems,',
1016  'workstationRDN' => 'ou=workstations,ou=systems,',
1017  'printerRDN' => 'ou=printers,ou=systems,',
1018  'phoneRDN' => 'ou=phones,ou=systems,',
1019  'componentRDN' => 'ou=netdevices,ou=systems,',
1020  'mobilePhoneRDN' => 'ou=mobile,ou=systems,',
1021 
1022  'inventoryRDN' => 'ou=inventory,',
1023 
1024  'ipmiRDN' => 'ou=ipmi,',
1025 
1026  'faxBlocklistRDN' => 'ou=gofax,ou=systems,',
1027  'aclRoleRDN' => 'ou=aclroles,',
1028  'phoneMacroRDN' => 'ou=macros,ou=asterisk,ou=configs,ou=systems,',
1029  'phoneConferenceRDN' => 'ou=conferences,ou=asterisk,ou=configs,ou=systems,',
1030 
1031  'faiBaseRDN' => 'ou=fai,ou=configs,ou=systems,',
1032  'faiScriptRDN' => 'ou=scripts,',
1033  'faiHookRDN' => 'ou=hooks,',
1034  'faiTemplateRDN' => 'ou=templates,',
1035  'faiVariableRDN' => 'ou=variables,',
1036  'faiProfileRDN' => 'ou=profiles,',
1037  'faiPackageRDN' => 'ou=packages,',
1038  'faiPartitionRDN' => 'ou=disk,',
1039 
1040  'debconfRDN' => 'ou=debconf,',
1041 
1042  'supannStructuresRDN' => 'ou=structures,',
1043 
1044  'sudoRDN' => 'ou=sudoers,',
1045 
1046  'netgroupRDN' => 'ou=netgroup,',
1047 
1048  'deviceRDN' => 'ou=devices,',
1049 
1050  'aliasRDN' => 'ou=alias,',
1051 
1052  'dsaRDN' => 'ou=dsa,',
1053 
1054  'mimetypeRDN' => 'ou=mime,'
1055  );
1056 
1057  /* Preset ou... */
1058  if ($config->get_cfg_value($name, '_not_set_') != '_not_set_') {
1059  $ou = $config->get_cfg_value($name);
1060  } elseif (isset($map[$name])) {
1061  $ou = $map[$name];
1062  return $ou;
1063  } else {
1064  return NULL;
1065  }
1066 
1067  if ($ou != '') {
1068  if (!preg_match('/^[^=]+=[^=]+/', $ou)) {
1069  $ou = "ou=$ou";
1070  } else {
1071  $ou = "$ou";
1072  }
1073 
1074  if (preg_match('/'.preg_quote($config->current['BASE'], '/').'$/', $ou)) {
1075  return $ou;
1076  } else {
1077  if (preg_match('/,$/', $ou)) {
1078  return $ou;
1079  } else {
1080  return "$ou,";
1081  }
1082  }
1083  } else {
1084  return '';
1085  }
1086 }
1087 
1095 function get_people_ou()
1096 {
1097  return get_ou('userRDN');
1098 }
1099 
1112 {
1113  global $config;
1114 
1115  $pattern = "/^[^,]+,".preg_quote(get_people_ou(), '/')."/i";
1116  $base = preg_replace($pattern, '', $dn);
1117 
1118  /* Set to base, if we're not on a correct subtree */
1119  if (!isset($config->idepartments[$base])) {
1120  $base = $config->current['BASE'];
1121  }
1122 
1123  return $base;
1124 }
1125 
1126 
1137 {
1138  global $config;
1139 
1140  if (isset($config)) {
1141  return ($config->get_cfg_value('strictNamingRules') == 'TRUE');
1142  }
1143  return TRUE;
1144 }
1145 
1170 function gen_locked_message($locks, $dn, $allow_readonly = FALSE)
1171 {
1172  session::set('dn', $dn);
1173  $remove = FALSE;
1174 
1175  /* Save variables from LOCK_VARS_TO_USE in session - for further editing */
1176  if ( session::is_set('LOCK_VARS_TO_USE') && count(session::get('LOCK_VARS_TO_USE'))) {
1177 
1178  $LOCK_VARS_USED_GET = array();
1179  $LOCK_VARS_USED_POST = array();
1180  $LOCK_VARS_USED_REQUEST = array();
1181  $LOCK_VARS_TO_USE = session::get('LOCK_VARS_TO_USE');
1182 
1183  foreach ($LOCK_VARS_TO_USE as $name) {
1184 
1185  if (empty($name)) {
1186  continue;
1187  }
1188 
1189  foreach ($_POST as $Pname => $Pvalue) {
1190  if (preg_match($name, $Pname)) {
1191  $LOCK_VARS_USED_POST[$Pname] = $_POST[$Pname];
1192  }
1193  }
1194 
1195  foreach ($_GET as $Pname => $Pvalue) {
1196  if (preg_match($name, $Pname)) {
1197  $LOCK_VARS_USED_GET[$Pname] = $_GET[$Pname];
1198  }
1199  }
1200 
1201  foreach ($_REQUEST as $Pname => $Pvalue) {
1202  if (preg_match($name, $Pname)) {
1203  $LOCK_VARS_USED_REQUEST[$Pname] = $_REQUEST[$Pname];
1204  }
1205  }
1206  }
1207  session::set('LOCK_VARS_TO_USE', array());
1208  session::set('LOCK_VARS_USED_GET', $LOCK_VARS_USED_GET);
1209  session::set('LOCK_VARS_USED_POST', $LOCK_VARS_USED_POST);
1210  session::set('LOCK_VARS_USED_REQUEST', $LOCK_VARS_USED_REQUEST);
1211  }
1212 
1213  /* Prepare and show template */
1214  $smarty = get_smarty();
1215  $smarty->assign('allow_readonly', $allow_readonly);
1216  if (is_array($dn)) {
1217  $msg = '<pre>';
1218  foreach ($dn as $sub_dn) {
1219  $msg .= "\n".$sub_dn.', ';
1220  }
1221  $msg = preg_replace("/, $/", "</pre>", $msg);
1222  } else {
1223  $msg = $dn;
1224  }
1225 
1226  $smarty->assign('dn', $msg);
1227  if ($remove) {
1228  $smarty->assign('action', _('Continue anyway'));
1229  } else {
1230  $smarty->assign('action', _('Edit anyway'));
1231  }
1232  $smarty->assign('message', sprintf(_("You're going to edit the LDAP entry/entries %s"), "<b>".$msg."</b>", ""));
1233  $smarty->assign('locks', $locks);
1234 
1235  return $smarty->fetch(get_template_path('islocked.tpl'));
1236 }
1237 
1238 
1252 function to_string ($value)
1253 {
1254  /* If this is an array, generate a text blob */
1255  if (is_array($value)) {
1256  $ret = '';
1257  foreach ($value as $line) {
1258  $ret .= $line."<br>\n";
1259  }
1260  return $ret;
1261  } else {
1262  return $value;
1263  }
1264 }
1265 
1275 function rewrite($s)
1276 {
1277  global $REWRITE;
1278 
1279  foreach ($REWRITE as $key => $val) {
1280  $s = str_replace("$key", "$val", $s);
1281  }
1282 
1283  return $s;
1284 }
1285 
1286 
1295 function dn2base($dn, $ou = NULL)
1296 {
1297  if ($ou === NULL) {
1298  if (get_people_ou() != '') {
1299  $dn = preg_replace('/,'.get_people_ou().'/i', ',', $dn);
1300  }
1301  if (get_ou('groupRDN') != '') {
1302  $dn = preg_replace('/,'.get_ou('groupRDN').'/i', ',', $dn);
1303  }
1304  } else {
1305  $dn = preg_replace("/,$ou/i", ',', $dn);
1306  }
1307 
1308  return preg_replace ('/^[^,]+,/i', '', $dn);
1309 }
1310 
1321 function check_command($cmdline)
1322 {
1323  $cmd = preg_replace("/ .*$/", '', $cmdline);
1324 
1325  /* Check if command exists in filesystem */
1326  if (!file_exists($cmd)) {
1327  return FALSE;
1328  }
1329 
1330  /* Check if command is executable */
1331  if (!is_executable($cmd)) {
1332  return FALSE;
1333  }
1334 
1335  return TRUE;
1336 }
1337 
1349 function print_header($image, $headline, $info = '')
1350 {
1351  $smarty = get_smarty();
1352  $smarty->assign('headline', $headline);
1353  $smarty->assign('headline_image', $image);
1354  $display = '';
1355 
1356  if ($info != '') {
1357  $display .= '<div class="pluginfo">'."\n";
1358  $display .= "$info";
1359  $display .= "</div>\n";
1360  $display .= "<div></div>\n";
1361  }
1362  return $display;
1363 }
1364 
1370 function back_to_main()
1371 {
1372  return '<br><p class="plugbottom"><input type=submit name="password_back" value="'.
1373  msgPool::backButton().'"></p><input type="hidden" name="ignore">';
1374 }
1375 
1383 function normalize_netmask($netmask)
1384 {
1385  /* Check for notation of netmask */
1386  if (!preg_match('/^([0-9]+\.){3}[0-9]+$/', $netmask)) {
1387  $num = (int)($netmask);
1388  $netmask = "";
1389 
1390  for ($byte = 0; $byte < 4; $byte++) {
1391  $result = 0;
1392 
1393  for ($i = 7; $i >= 0; $i--) {
1394  if ($num-- > 0) {
1395  $result += pow(2, $i);
1396  }
1397  }
1398 
1399  $netmask .= $result.".";
1400  }
1401 
1402  return preg_replace('/\.$/', '', $netmask);
1403  }
1404 
1405  return $netmask;
1406 }
1407 
1408 
1433 function netmask_to_bits($netmask)
1434 {
1435  $nm = explode('.', $netmask, 4);
1436 
1437  $res = 0;
1438  for ($n = 0; $n < 4; $n++) {
1439  $start = 255;
1440 
1441  for ($i = 0; $i < 8; $i++) {
1442  if ($start == (int)($nm[$n])) {
1443  $res += 8 - $i;
1444  break;
1445  }
1446  $start -= pow(2, $i);
1447  }
1448  }
1449 
1450  return $res;
1451 }
1452 
1453 
1457 function _recurse_gen_uids($rule, $variables)
1458 {
1459  $result = array();
1460 
1461  if (!count($variables)) {
1462  return array($rule);
1463  }
1464 
1465  reset($variables);
1466  $key = key($variables);
1467  $val = current($variables);
1468  unset($variables[$key]);
1469 
1470  foreach ($val as $possibility) {
1471  $nrule = str_replace("{$key}", $possibility, $rule);
1472  $result = array_merge($result, _recurse_gen_uids($nrule, $variables));
1473  }
1474 
1475  return $result;
1476 }
1477 
1478 
1491 function gen_uids($rule, $attributes)
1492 {
1493  global $config;
1494 
1495  // Attributes should be arrays
1496  foreach ($attributes as $name => $value) {
1497  $attributes[$name] = array($value);
1498  }
1499 
1500  /* Search for keys and fill the variables array with all
1501  possible values for that key. */
1502  $stripped = $rule;
1503  $variables = array();
1504 
1505  for ($pos = 0; preg_match('/%([^%]+)%/', $stripped, $m, PREG_OFFSET_CAPTURE, $pos); ) {
1506  $variables[$pos] = templateHandling::parseMask($m[1][0], $attributes);
1507  $replace = '{'.$pos.'}';
1508  $stripped = substr_replace($stripped, $replace, $m[0][1], strlen($m[0][0]));
1509  $pos = $m[0][1] + strlen($replace);
1510  }
1511 
1512  /* Recurse through all possible combinations */
1513  $proposed = _recurse_gen_uids($stripped, $variables);
1514 
1515  /* Get list of used ID's */
1516  $ldap = $config->get_ldap_link();
1517  $ldap->cd($config->current['BASE']);
1518 
1519  /* Remove used uids and watch out for id tags */
1520  $ret = array();
1521  foreach ($proposed as $uid) {
1522  /* Check for id tag and modify uid if needed */
1523  if (preg_match('/\{id(:|!)(\d+)}/', $uid, $m)) {
1524  $size = $m[2];
1525 
1526  $start = ($m[1] == ":" ? 0 : -1);
1527  for ($i = $start, $p = pow(10, $size) - 1; $i < $p; $i++) {
1528  if ($i == -1) {
1529  $number = "";
1530  } else {
1531  $number = sprintf("%0".$size."d", $i + 1);
1532  }
1533  $res = preg_replace('/{id(:|!)\d+}/', $number, $uid);
1534 
1535  $ldap->search('(uid='.ldap_escape_f(preg_replace('/[{}]/', '', $res)).')', array('dn'));
1536  if ($ldap->count() == 0) {
1537  $uid = $res;
1538  break;
1539  }
1540  }
1541 
1542  /* Remove link if nothing has been found */
1543  $uid = preg_replace('/{id(:|!)\d+}/', '', $uid);
1544  }
1545 
1546  if (preg_match('/\{id#\d+}/', $uid)) {
1547  $size = preg_replace('/^.*{id#(\d+)}.*$/', '\\1', $uid);
1548 
1549  while (TRUE) {
1550  $number = sprintf("%0".$size."d", random_int(0, pow(10, $size) - 1));
1551  $res = preg_replace('/{id#(\d+)}/', $number, $uid);
1552  $ldap->search('(uid='.ldap_escape_f(preg_replace('/[{}]/', '', $res)).')', array('dn'));
1553  if ($ldap->count() == 0) {
1554  $uid = $res;
1555  break;
1556  }
1557  }
1558 
1559  /* Remove link if nothing has been found */
1560  $uid = preg_replace('/{id#\d+}/', '', $uid);
1561  }
1562 
1563  /* Don't assign used ones */
1564  $ldap->search('(uid='.ldap_escape_f(preg_replace('/[{}]/', '', $uid)).')', array('dn'));
1565  if ($ldap->count() == 0) {
1566  /* Add uid, but remove {} first. These are invalid anyway. */
1567  $uid = preg_replace('/[{}]/', '', $uid);
1568  if ($uid != '') {
1569  $ret[] = $uid;
1570  }
1571  }
1572  }
1573 
1574  return array_unique($ret);
1575 }
1576 
1577 
1590 function to_byte($value)
1591 {
1592  $value = strtolower(trim($value));
1593 
1594  if (!is_numeric(substr($value, -1))) {
1595 
1596  switch (substr($value, -1)) {
1597  case 'g':
1598  $mult = 1073741824;
1599  break;
1600  case 'm':
1601  $mult = 1048576;
1602  break;
1603  case 'k':
1604  $mult = 1024;
1605  break;
1606  }
1607 
1608  return $mult * (int)substr($value, 0, -1);
1609  } else {
1610  return $value;
1611  }
1612 }
1613 
1623 function humanReadableSize ($bytes, $precision = 2)
1624 {
1625  $format = array(
1626  _('%sB'),
1627  _('%sKiB'),
1628  _('%sMiB'),
1629  _('%sGiB'),
1630  _('%sTiB'),
1631  _('%sPiB'),
1632  _('%sEiB'),
1633  _('%sZiB'),
1634  _('%sYiB')
1635  );
1636  if ($bytes == 0) {
1637  return sprintf($format[0], '0');
1638  }
1639  $base = log($bytes) / log(1024);
1640 
1641  return sprintf($format[floor($base)], round(pow(1024, $base - floor($base)), $precision));
1642 }
1643 
1644 
1657 function in_array_ics($value, array $items)
1658 {
1659  return preg_grep('/^'.preg_quote($value, '/').'$/i', $items);
1660 }
1661 
1662 
1664 function generate_alphabet($count = 10)
1665 {
1666  $characters = _("*ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789");
1667  $alphabet = "";
1668  $c = 0;
1669 
1670  /* Fill cells with charaters */
1671  for ($i = 0, $l = mb_strlen($characters, 'UTF8'); $i < $l; $i++) {
1672  if ($c == 0) {
1673  $alphabet .= "<tr>";
1674  }
1675 
1676  $ch = mb_substr($characters, $i, 1, "UTF8");
1677  $alphabet .= "<td><a class=\"alphaselect\" href=\"main.php?plug=".
1678  validate($_GET['plug'])."&amp;search=".$ch."\">&nbsp;".$ch."&nbsp;</a></td>";
1679 
1680  if ($c++ == $count) {
1681  $alphabet .= "</tr>";
1682  $c = 0;
1683  }
1684  }
1685 
1686  /* Fill remaining cells */
1687  while ($c++ <= $count) {
1688  $alphabet .= "<td>&nbsp;</td>";
1689  }
1690 
1691  return $alphabet;
1692 }
1693 
1694 
1702 function validate($string)
1703 {
1704  return strip_tags(str_replace('\0', '', $string));
1705 }
1706 
1707 
1718 function rmdirRecursive($path, $followLinks = FALSE)
1719 {
1720  $dir = opendir($path);
1721  while ($entry = readdir($dir)) {
1722  if (is_file($path."/".$entry) || ((!$followLinks) && is_link($path."/".$entry))) {
1723  unlink($path."/".$entry);
1724  } elseif (is_dir($path."/".$entry) && ($entry != '.') && ($entry != '..')) {
1725  rmdirRecursive($path."/".$entry);
1726  }
1727  }
1728  closedir($dir);
1729  return rmdir($path);
1730 }
1731 
1732 
1745 function scan_directory($path, $sort_desc = FALSE)
1746 {
1747  $ret = FALSE;
1748 
1749  /* is this a dir ? */
1750  if (is_dir($path)) {
1751 
1752  /* is this path a readable one */
1753  if (is_readable($path)) {
1754 
1755  /* Get contents and write it into an array */
1756  $ret = array();
1757 
1758  $dir = opendir($path);
1759 
1760  /* Is this a correct result ?*/
1761  if ($dir) {
1762  while ($fp = readdir($dir)) {
1763  $ret[] = $fp;
1764  }
1765  }
1766  }
1767  }
1768  /* Sort array ascending , like scandir */
1769  sort($ret);
1770 
1771  /* Sort descending if parameter is sort_desc is set */
1772  if ($sort_desc) {
1773  $ret = array_reverse($ret);
1774  }
1775 
1776  return $ret;
1777 }
1778 
1779 
1785 function clean_smarty_compile_dir($directory)
1786 {
1787  if (is_dir($directory) && is_readable($directory)) {
1788  // Set revision filename to REVISION
1789  $revision_file = $directory."/REVISION";
1790 
1791  /* Is there a stamp containing the current revision? */
1792  if (file_exists($revision_file)) {
1793  // check for "$config->...['CONFIG']/revision" and the
1794  // contents should match the revision number
1795  if (!compare_revision($revision_file, FD_VERSION)) {
1796  // If revision differs, clean compile directory
1797  foreach (scan_directory($directory) as $file) {
1798  if (($file == ".") || ($file == "..")) {
1799  continue;
1800  }
1801  if (is_file($directory."/".$file)) {
1802  // delete file
1803  if (!unlink($directory."/".$file)) {
1804  msg_dialog::display(_("Internal error"), sprintf(_("File '%s' could not be deleted. Try fusiondirectory-setup --check-directories to fix permissions."), $directory."/".$file), ERROR_DIALOG);
1805  }
1806  }
1807  }
1808  } else {
1809  // Revision matches, nothing to do
1810  }
1811  }
1812  /* If the file does not exists or has just been deleted */
1813  if (!file_exists($revision_file)) {
1814  // create revision file
1815  create_revision($revision_file, FD_VERSION);
1816  }
1817  }
1818 }
1819 
1831 function create_revision($revision_file, $revision)
1832 {
1833  $result = FALSE;
1834 
1835  if (is_dir(dirname($revision_file)) && is_writable(dirname($revision_file))) {
1836  if ($fh = fopen($revision_file, 'w')) {
1837  if (fwrite($fh, $revision)) {
1838  $result = TRUE;
1839  }
1840  fclose($fh);
1841  }
1842  } else {
1843  msg_dialog::display(_('Internal error'), _('Cannot write to revision file!'), ERROR_DIALOG);
1844  }
1845 
1846  return $result;
1847 }
1848 
1859 function compare_revision($revision_file, $revision)
1860 {
1861  // FALSE means revision differs
1862  $result = FALSE;
1863 
1864  if (file_exists($revision_file) && is_readable($revision_file)) {
1865  // Open file
1866  if ($fh = fopen($revision_file, "r")) {
1867  // Compare File contents with current revision
1868  if ($revision == fread($fh, filesize($revision_file))) {
1869  $result = TRUE;
1870  }
1871  // Close file
1872  fclose($fh);
1873  } else {
1874  msg_dialog::display(_('Internal error'), _('Cannot read revision file!'), ERROR_DIALOG);
1875  }
1876  }
1877 
1878  return $result;
1879 }
1880 
1881 
1900 function array_key_ics($ikey, array $items)
1901 {
1902  $tmp = array_change_key_case($items, CASE_LOWER);
1903  $ikey = strtolower($ikey);
1904  if (isset($tmp[$ikey])) {
1905  return $tmp[$ikey];
1906  }
1907 
1908  return '';
1909 }
1910 
1911 
1921 function array_differs($src, $dst)
1922 {
1923  /* If the count is differing, the arrays differ */
1924  if (count ($src) != count ($dst)) {
1925  return TRUE;
1926  }
1927 
1928  return (count(array_diff($src, $dst)) != 0);
1929 }
1930 
1940 function array_differs_recursive($src, $dst)
1941 {
1942  if (is_array($src)) {
1943  if (!is_array($dst)) {
1944  return TRUE;
1945  }
1946  if (count($src) != count($dst)) {
1947  return TRUE;
1948  }
1949  foreach ($src as $key => $value) {
1950  if (!isset($dst[$key])) {
1951  return TRUE;
1952  }
1953  if (array_differs_recursive($dst[$key], $value)) {
1954  return TRUE;
1955  }
1956  }
1957  return FALSE;
1958  }
1959  return ((string)$src != (string)$dst);
1960 }
1961 
1968 function normalizeLdap($input)
1969 {
1970  trigger_error('deprecated, use ldap_escape_f');
1971  return addcslashes($input, '*()\\/');
1972 }
1973 
1979 function check_schema($cfg)
1980 {
1981  $checks = array();
1982 
1983  /* Get objectclasses */
1984  $ldapObj = new LDAP($cfg['admin'], $cfg['password'], $cfg['connection'], FALSE, $cfg['tls']);
1985  $ldap = new ldapMultiplexer($ldapObj);
1986  $objectclasses = $ldap->get_objectclasses(TRUE);
1987  if (count($objectclasses) == 0) {
1988  msg_dialog::display(_('LDAP warning'), _('Cannot get schema information from server. No schema check possible!'), WARNING_DIALOG);
1989  return $checks;
1990  }
1991 
1992  /* This is the default block used for each entry.
1993  * to avoid unset indexes.
1994  */
1995  $def_check = array(
1996  'SCHEMA_FILE' => '',
1997  'CLASSES_REQUIRED' => array(),
1998  'STATUS' => FALSE,
1999  'IS_MUST_HAVE' => FALSE,
2000  'MSG' => '',
2001  'INFO' => ''
2002  );
2003 
2004  /* FusionDirectory core schemas */
2005 
2006  /* core-fd */
2007  $checks['core-fd'] = $def_check;
2008  $checks['core-fd']['SCHEMA_FILE'] = 'core-fd.schema';
2009  $checks['core-fd']['CLASSES_REQUIRED'] = array('fdLockEntry');
2010  $checks['core-fd']['IS_MUST_HAVE'] = TRUE;
2011  $checks['core-fd']['INFO'] = _('Main FusionDirectory schema');
2012 
2013  /* core-fd-conf */
2014  $checks['core-fd-conf'] = $def_check;
2015  $checks['core-fd-conf']['SCHEMA_FILE'] = 'core-fd-conf.schema';
2016  $checks['core-fd-conf']['CLASSES_REQUIRED'] = array('fusionDirectoryConf');
2017  $checks['core-fd-conf']['IS_MUST_HAVE'] = TRUE;
2018  $checks['core-fd-conf']['INFO'] = _('Schema used to store FusionDirectory configuration');
2019 
2020  /* ldapns */
2021  $checks['ldapns'] = $def_check;
2022  $checks['ldapns']['SCHEMA_FILE'] = 'ldapns.schema';
2023  $checks['ldapns']['CLASSES_REQUIRED'] = array('hostObject');
2024  $checks['ldapns']['IS_MUST_HAVE'] = FALSE;
2025  $checks['ldapns']['INFO'] = _('Used to store trust mode information in users or groups.');
2026 
2027  /* template-fd */
2028  $checks['template-fd'] = $def_check;
2029  $checks['template-fd']['SCHEMA_FILE'] = 'template-fd.schema';
2030  $checks['template-fd']['CLASSES_REQUIRED'] = array('fdTemplate');
2031  $checks['template-fd']['IS_MUST_HAVE'] = FALSE;
2032  $checks['template-fd']['INFO'] = _('Used to store templates.');
2033 
2034  if (class_available('posixAccount')) {
2035  /* nis */
2036  $checks['nis'] = $def_check;
2037  $checks['nis']['SCHEMA_FILE'] = 'nis.schema';
2038  $checks['nis']['CLASSES_REQUIRED'] = array('posixAccount');
2039  $checks['nis']['IS_MUST_HAVE'] = FALSE;
2040  $checks['nis']['INFO'] = _('Used to store POSIX information.');
2041  }
2042 
2043  foreach ($checks as $name => $value) {
2044  foreach ($value['CLASSES_REQUIRED'] as $class) {
2045  if (!isset($objectclasses[$class])) {
2046  $checks[$name]['STATUS'] = FALSE;
2047  if ($value['IS_MUST_HAVE']) {
2048  $checks[$name]['MSG'] = sprintf(_('Missing required object class "%s"!'), $class);
2049  } else {
2050  $checks[$name]['MSG'] = sprintf(_('Missing optional object class "%s"!'), $class);
2051  }
2052  } else {
2053  $checks[$name]['STATUS'] = TRUE;
2054  $checks[$name]['MSG'] = sprintf(_('Class(es) available'));
2055  }
2056  }
2057  }
2058 
2059  $checks['posixGroup'] = $def_check;
2060  $checks['posixGroup']['SCHEMA_FILE'] = 'nis.schema';
2061  $checks['posixGroup']['CLASSES_REQUIRED'] = array('posixGroup');
2062  $checks['posixGroup']['STATUS'] = TRUE;
2063  $checks['posixGroup']['MSG'] = '';
2064  $checks['posixGroup']['INFO'] = '';
2065 
2066  if (isset($objectclasses['posixGroup'])) {
2067  $checks['posixGroup']['IS_MUST_HAVE'] = TRUE;
2068 
2069  /* Depending on mixed groups plugin installation status, we need different schema configurations */
2070  if (class_available('mixedGroup') && isset($objectclasses['posixGroup']['STRUCTURAL'])) {
2071  $checks['posixGroup']['STATUS'] = FALSE;
2072  $checks['posixGroup']['MSG'] = _('You have installed the mixed groups plugin, but your schema configuration does not support this.');
2073  $checks['posixGroup']['INFO'] = _('In order to use mixed groups the objectClass "posixGroup" must be AUXILIARY');
2074  } elseif (!class_available('mixedGroup') && !isset($objectclasses['posixGroup']['STRUCTURAL'])) {
2075  $checks['posixGroup']['STATUS'] = FALSE;
2076  $checks['posixGroup']['MSG'] = _('Your schema is configured to support mixed groups, but this plugin is not present.');
2077  $checks['posixGroup']['INFO'] = _('The objectClass "posixGroup" must be STRUCTURAL');
2078  }
2079  }
2080 
2081  return $checks;
2082 }
2083 
2091 function get_languages($languages_in_own_language = FALSE, $strip_region_tag = FALSE)
2092 {
2093  /* locales in english */
2094  $tmp_english = array(
2095  "ar" => "Arabic",
2096  "ca_ES" => "Catalan",
2097  "cs_CZ" => "Czech",
2098  "de_DE" => "German",
2099  "el_GR" => "Greek",
2100  "en_US" => "English",
2101  "es_CO" => "Colombian Spanish",
2102  "es_ES" => "Spanish",
2103  "es_VE" => "Venezuelan",
2104  "fa_IR" => "Persian",
2105  "fi_FI" => "Finnish",
2106  "fr_FR" => "French",
2107  "it_IT" => "Italian",
2108  "nb" => "Norwegian Bokmål",
2109  "nl_NL" => "Dutch",
2110  "pl_PL" => "Polish",
2111  "pt" => "Portuguese",
2112  "pt_BR" => "Brazilian",
2113  "ru_RU" => "Russian",
2114  "vi_VN" => "Vietnamese",
2115  "sv_SE" => "Swedish",
2116  "zh_CN" => "Chinese",
2117  );
2118 
2119  $ret = array();
2120  if ($languages_in_own_language) {
2121  /* locales in their own language */
2122  $tmp_ownlang = array(
2123  "ar" => "عربية",
2124  "ca_ES" => "Català",
2125  "cs_CZ" => "Česky",
2126  "de_DE" => "Deutsch",
2127  "el_GR" => "ελληνικά",
2128  "en_US" => "English",
2129  "es_CO" => "Español Colombiano",
2130  "es_ES" => "Español",
2131  "es_VE" => "Castellano",
2132  "fa_IR" => "پارسی",
2133  "fi_FI" => "Suomi",
2134  "fr_FR" => "Français",
2135  "it_IT" => "Italiano",
2136  "nb" => "Norsk bokmål",
2137  "nl_NL" => "Nederlands",
2138  "pl_PL" => "Polski",
2139  "pt" => "Portuguese",
2140  "pt_BR" => "Portuguese (Brazil)",
2141  "ru_RU" => "русский язык",
2142  "vi_VN" => "Tiếng Việt",
2143  "sv_SE" => "Svenska",
2144  "zh_CN" => "中文, 汉语, 漢語",
2145  );
2146 
2147  foreach ($tmp_english as $key => $name) {
2148  $label = _($name)." (".$tmp_ownlang[$key].")";
2149  if ($strip_region_tag) {
2150  $ret[preg_replace("/^([^_]*).*$/", "\\1", $key)] = $label;
2151  } else {
2152  $ret[$key] = $label;
2153  }
2154  }
2155  } else {
2156  foreach ($tmp_english as $key => $name) {
2157  if ($strip_region_tag) {
2158  $ret[preg_replace("/^([^_]*).*/", "\\1", $key)] = _($name);
2159  } else {
2160  $ret[$key] = _($name);
2161  }
2162  }
2163  }
2164  return $ret;
2165 }
2166 
2170 function language_is_rtl ($lang)
2171 {
2172  $lang = preg_replace('/\.UTF-8$/', '', $lang);
2173 
2174  if (preg_match('/^fa_/', $lang)) {
2175  return TRUE;
2176  }
2177  return FALSE;
2178 }
2179 
2180 
2191 function get_post($name)
2192 {
2193  if (!isset($_POST[$name])) {
2194  trigger_error("Requested POST value (".$name.") does not exists, you should add a check to prevent this message.");
2195  return FALSE;
2196  }
2197 
2198  return validate($_POST[$name]);
2199 }
2200 
2205 {
2206  global $class_mapping;
2207  if (isset($class_mapping) && is_array($class_mapping)) {
2208  foreach (array_keys($class_mapping) as $class) {
2209  if (preg_match("/^".$cls."$/i", $class)) {
2210  return $class;
2211  }
2212  }
2213  }
2214  return FALSE;
2215 }
2216 
2217 
2232 function change_password ($dn, $password, $hash = "")
2233 {
2234  $userTabs = objects::open($dn, 'user');
2235  $userTab = $userTabs->getBaseObject();
2236  $userTab->userPassword = array(
2237  $hash,
2238  $password,
2239  $password,
2240  $userTab->userPassword,
2241  $userTab->attributesAccess['userPassword']->isLocked()
2242  );
2243  $userTabs->save_object();
2244  $error = $userTabs->save();
2245  if (!empty($error)) {
2246  return $error;
2247  }
2248 
2249  return TRUE;
2250 }
2251 
2252 /* Lock or unlock samba account */
2253 function lock_samba_account($mode, array $attrs)
2254 {
2255  global $config;
2256  if (!isset($attrs['sambaNTPassword'][0])) {
2257  return array();
2258  }
2259  $modify = array('sambaNTPassword' => $attrs['sambaNTPassword'][0]);
2260  if ($config->get_cfg_value("sambaGenLMPassword", "FALSE") == "TRUE") {
2261  $modify['sambaLMPassword'] = $attrs['sambaLMPassword'][0];
2262  } else {
2263  $modify['sambaLMPassword'] = array();
2264  }
2265  foreach ($modify as &$pwd) {
2266  if (is_array($pwd)) {
2267  continue;
2268  }
2269  if ($mode == 'LOCK') {
2270  /* Lock entry */
2271  if (!preg_match('/^\!/', $pwd)) {
2272  $pwd = '!'.$pwd;
2273  }
2274  } else {
2275  /* Unlock entry */
2276  $pwd = preg_replace("/^\!/", "", $pwd);
2277  }
2278  }
2279  unset($pwd);
2280  return $modify;
2281 }
2282 
2283 /* Lock or unlock ssh account */
2284 function lock_ssh_account($mode, array $attrs, &$modify)
2285 {
2286  if (!isset($attrs['sshPublicKey'])) {
2287  return;
2288  }
2289  $modify['sshPublicKey'] = array();
2290  for ($i = 0; $i < $attrs['sshPublicKey']['count']; ++$i) {
2291  if ($mode == 'LOCK') {
2292  $modify['sshPublicKey'][] = preg_replace('/^/', 'disabled-', $attrs['sshPublicKey'][$i]);
2293  } else {
2294  $modify['sshPublicKey'][] = preg_replace('/^disabled-/', '', $attrs['sshPublicKey'][$i]);
2295  }
2296  }
2297 }
2298 
2299 
2312 function getEntryCSN($dn)
2313 {
2314  global $config;
2315  if (empty($dn) || !is_object($config)) {
2316  return '';
2317  }
2318 
2319  /* Get attribute that we should use as serial number */
2320  $attr = $config->get_cfg_value('modificationDetectionAttribute');
2321  if ($attr != '') {
2322  $ldap = $config->get_ldap_link();
2323  $ldap->cat($dn, array($attr));
2324  $csn = $ldap->fetch();
2325  if (isset($csn[$attr][0])) {
2326  return $csn[$attr][0];
2327  }
2328  }
2329  return '';
2330 }
2331 
2341 function send_binary_content($data, $name, $type = "application/octet-stream")
2342 {
2343  header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
2344  header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
2345  header("Cache-Control: no-cache");
2346  header("Pragma: no-cache");
2347  header("Cache-Control: post-check=0, pre-check=0");
2348  header("Content-type: ".$type);
2349 
2350  /* Strip name if it is a complete path */
2351  if (preg_match ("/\//", $name)) {
2352  $name = basename($name);
2353  }
2354 
2355  /* force download dialog */
2356  header('Content-Disposition: attachment; filename="'.$name.'"');
2357 
2358  echo $data;
2359  exit();
2360 }
2361 
2362 
2363 function reverse_html_entities($str, $type = ENT_QUOTES, $charset = "UTF-8")
2364 {
2365  if (is_string($str)) {
2366  return htmlentities($str, $type, $charset);
2367  } elseif (is_array($str)) {
2368  foreach ($str as $name => $value) {
2369  $str[$name] = reverse_html_entities($value, $type, $charset);
2370  }
2371  }
2372  return $str;
2373 }
2374 
2375 
2386 function xmlentities($str)
2387 {
2388  if (is_string($str)) {
2389  return htmlspecialchars($str, ENT_QUOTES);
2390  } elseif (is_array($str)) {
2391  foreach ($str as $name => $value) {
2392  $str[$name] = xmlentities($value);
2393  }
2394  }
2395  return $str;
2396 }
2397 
2401 function get_random_char ()
2402 {
2403  $randno = rand (0, 63);
2404  if ($randno < 12) {
2405  // Digits, '/' and '.'
2406  return chr($randno + 46);
2407  } elseif ($randno < 38) {
2408  // Uppercase
2409  return chr($randno + 53);
2410  } else {
2411  // Lowercase
2412  return chr($randno + 59);
2413  }
2414 }
2415 
2423 function cred_decrypt($input, $password)
2424 {
2425  /************************* Inspired by Crypt/CBC.pm *******************************/
2426  $input = pack('H*', $input);
2427  if (substr($input, 0, 8) != 'Salted__') {
2428  throw new FusionDirectoryException("Invalid hash header: expected 'Salted__', found '".substr($input, 0, 8)."'");
2429  }
2430  $salt = substr($input, 8, 8);
2431  $input = substr($input, 16);
2432 
2433  $key_len = 32;
2434  $iv_len = openssl_cipher_iv_length('aes-256-cbc');
2435 
2436  $data = '';
2437  $d = '';
2438  while (strlen($data) < $key_len + $iv_len) {
2439  $d = md5($d . $password . $salt, TRUE);
2440  $data .= $d;
2441  }
2442  $key = substr($data, 0, $key_len);
2443  $iv = substr($data, $key_len, $iv_len);
2444 
2445  return openssl_decrypt($input, 'aes-256-cbc', $key, OPENSSL_RAW_DATA, $iv);
2446 }
2447 
2448 
2449 function get_object_info()
2450 {
2451  return session::get('objectinfo');
2452 }
2453 
2454 
2455 function set_object_info($str = "")
2456 {
2457  session::set('objectinfo', $str);
2458 }
2459 
2469 function isIpInNet($ip, $net, $mask)
2470 {
2471  // Move to long ints
2472  $ip = ip2long($ip);
2473  $net = ip2long($net);
2474  $mask = ip2long($mask);
2475 
2476  // Mask given IP with mask. If it returns "net", we're in...
2477  return (($ip & $mask) == $net);
2478 }
2479 
2483 function expandIPv6 ($ip)
2484 {
2485  $hex = unpack('H*hex', inet_pton($ip));
2486  $ip = substr(preg_replace('/([A-f0-9]{4})/', "$1:", $hex['hex']), 0, -1);
2487 
2488  return $ip;
2489 }
2490 
2491 /* Mark the occurance of a string with a span */
2492 function mark($needle, $haystack)
2493 {
2494  $result = '';
2495 
2496  while (preg_match('/^(.*)('.preg_quote($needle).')(.*)$/i', $haystack, $matches)) {
2497  $result .= $matches[1].'<span class="mark">'.$matches[2].'</span>';
2498  $haystack = $matches[3];
2499  }
2500 
2501  return $result.$haystack;
2502 }
2503 
2504 function reset_errors()
2505 {
2506  session::set('errors', '');
2507  session::set('errorsAlreadyPosted', array());
2508  session::set('LastError', '');
2509 }
2510 
2511 function load_all_classes()
2512 {
2513  global $BASE_DIR, $class_list, $class_mapping;
2514  /* Initially load all classes */
2515  $class_list = get_declared_classes();
2516  foreach ($class_mapping as $class => $path) {
2517  if (!in_array($class, $class_list)) {
2518  if (is_readable("$BASE_DIR/$path")) {
2519  require_once("$BASE_DIR/$path");
2520  } else {
2521  msg_dialog::display(_('Fatal error'),
2522  sprintf(_("Cannot locate file '%s' - please run '%s' to fix this"),
2523  "$BASE_DIR/$path", '<b>fusiondirectory-setup</b>'), FATAL_ERROR_DIALOG);
2524  exit;
2525  }
2526  }
2527  }
2528 }
2529 
2530 function initLanguage($lang = NULL)
2531 {
2532  global $BASE_DIR;
2533  if ($lang === NULL) {
2534  $lang = get_browser_language();
2535  }
2536 
2537  putenv('LANGUAGE=');
2538  putenv("LANG=$lang");
2539  setlocale(LC_ALL, $lang);
2540  $GLOBALS['t_language'] = $lang;
2541  $GLOBALS['t_gettext_message_dir'] = $BASE_DIR.'/locale/';
2542 
2543  /* Set the text domain as 'fusiondirectory' */
2544  $domain = 'fusiondirectory';
2545  bindtextdomain($domain, LOCALE_DIR);
2546  textdomain($domain);
2547  if ($_SERVER['REQUEST_METHOD'] != 'POST') {
2548  @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__, $lang, 'Setting language to');
2549  }
2550 
2551  $ret = FALSE;
2552 
2553  /* Reset plist cache if language changed */
2554  if ((!session::global_is_set('lang')) || (session::global_get('lang') != $lang)) {
2555  $ret = TRUE;
2556  if (session::global_is_set('plist')) {
2557  if ($_SERVER['REQUEST_METHOD'] != 'POST') {
2558  @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__, session::global_get('lang'), 'Plist already loaded with language');
2559  }
2560  session::global_un_set('plist');
2561  session::global_set('lang', $lang);
2562  load_plist();
2563  }
2564  }
2565 
2566  session::global_set('lang', $lang);
2567  return $ret;
2568 }
2569 
2570 if (!function_exists('ldap_escape')) {
2571  /* This bloc is for PHP<5.6 */
2572  define('LDAP_ESCAPE_FILTER', 0x01);
2573  define('LDAP_ESCAPE_DN', 0x02);
2574 
2582  function ldap_escape($subject, $ignore = '', $flags = 0)
2583  {
2584  static $charMaps = array(
2585  LDAP_ESCAPE_FILTER => array('\\', '*', '(', ')', "\x00"),
2586  LDAP_ESCAPE_DN => array('\\', ',', '=', '+', '<', '>', ';', '"', '#'),
2587  );
2588 
2589  // Pre-process the char maps on first call
2590  if (!isset($charMaps[0])) {
2591  $charMaps[0] = array();
2592  for ($i = 0; $i < 256; $i++) {
2593  $charMaps[0][chr($i)] = sprintf('\\%02x', $i);
2594  }
2595 
2596  for ($i = 0, $l = count($charMaps[LDAP_ESCAPE_FILTER]); $i < $l; $i++) {
2597  $chr = $charMaps[LDAP_ESCAPE_FILTER][$i];
2598  unset($charMaps[LDAP_ESCAPE_FILTER][$i]);
2599  $charMaps[LDAP_ESCAPE_FILTER][$chr] = $charMaps[0][$chr];
2600  }
2601 
2602  for ($i = 0, $l = count($charMaps[LDAP_ESCAPE_DN]); $i < $l; $i++) {
2603  $chr = $charMaps[LDAP_ESCAPE_DN][$i];
2604  unset($charMaps[LDAP_ESCAPE_DN][$i]);
2605  $charMaps[LDAP_ESCAPE_DN][$chr] = $charMaps[0][$chr];
2606  }
2607  }
2608 
2609  // Create the base char map to escape
2610  $flags = (int)$flags;
2611  $charMap = array();
2612  if ($flags & LDAP_ESCAPE_FILTER) {
2613  $charMap += $charMaps[LDAP_ESCAPE_FILTER];
2614  }
2615  if ($flags & LDAP_ESCAPE_DN) {
2616  $charMap += $charMaps[LDAP_ESCAPE_DN];
2617  }
2618  if (!$charMap) {
2619  $charMap = $charMaps[0];
2620  }
2621 
2622  // Remove any chars to ignore from the list
2623  $ignore = (string)$ignore;
2624  for ($i = 0, $l = strlen($ignore); $i < $l; $i++) {
2625  unset($charMap[$ignore[$i]]);
2626  }
2627 
2628  // Do the main replacement
2629  $result = strtr($subject, $charMap);
2630 
2631  // Encode leading/trailing spaces if LDAP_ESCAPE_DN is passed
2632  if ($flags & LDAP_ESCAPE_DN) {
2633  if ($result[0] === ' ') {
2634  $result = '\\20' . substr($result, 1);
2635  }
2636  if ($result[strlen($result) - 1] === ' ') {
2637  $result = substr($result, 0, -1) . '\\20';
2638  }
2639  }
2640 
2641  return $result;
2642  }
2643 }
2644 
2645 if (!function_exists('random_int')) {
2646  // PHP<7, we fallback on openssl_random_pseudo_bytes
2647  function random_int($min, $max)
2648  {
2649  $range = $max - $min;
2650  if ($range <= 0) {
2651  throw new Exception('Invalid range passed to random_int');
2652  }
2653 
2654  $log = log($range, 2);
2655  // length in bytes
2656  $nbBytes = (int) ($log / 8) + 1;
2657  // length in bits
2658  $nbBits = (int) $log + 1;
2659  // set all lower bits to 1
2660  $filter = pow(2, $nbBits) - 1;
2661  if ($filter >= PHP_INT_MAX) {
2662  $filter = PHP_INT_MAX;
2663  }
2664  do {
2665  $randomBytes = openssl_random_pseudo_bytes($nbBytes, $strong);
2666  if (!$strong || ($randomBytes === FALSE)) {
2667  throw new Exception('Failed to get random bytes');
2668  }
2669  $rnd = hexdec(bin2hex($randomBytes));
2670  // discard irrelevant bits
2671  $rnd = $rnd & $filter;
2672  } while ($rnd > $range);
2673  return $min + $rnd;
2674  }
2675 }
2676 
2677 function ldap_escape_f($str, $ignore = '')
2678 {
2679  return ldap_escape($str, $ignore, LDAP_ESCAPE_FILTER);
2680 }
2681 
2682 function ldap_escape_dn($str, $ignore = '')
2683 {
2684  return ldap_escape($str, $ignore, LDAP_ESCAPE_DN);
2685 }
2686 
2687 function mail_utf8($to, $from_user, $from_email, $subject, $message, $type = 'plain')
2688 {
2689  $subject = "=?UTF-8?B?".base64_encode($subject)."?=";
2690  if ($from_user) {
2691  $from_user = "=?UTF-8?B?".base64_encode($from_user)."?=";
2692  $headers = "From: $from_user <$from_email>\r\n";
2693  $headers .= "Reply-To: $from_user <$from_email>\r\n";
2694  } else {
2695  $headers = "From: <$from_email>\r\n";
2696  $headers .= "Reply-To: <$from_email>\r\n";
2697  }
2698  $headers .= "MIME-Version: 1.0" . "\r\n" .
2699  "Content-type: text/$type; charset=UTF-8" . "\r\n";
2700 
2701  $additional_parameters = "-f".$from_email;
2702 
2703  return mail($to, $subject, $message, $headers, $additional_parameters);
2704 }
2705 
2706 /* Calls fopen, gives errors as an array if any, file handle if successful */
2707 function fopenWithErrorHandling()
2708 {
2709  $args = func_get_args();
2710  $errors = array();
2711  set_error_handler(
2712  function ($errno, $errstr, $errfile, $errline, $errcontext) use (&$errors)
2713  {
2714  $errors[] = $errstr;
2715  }
2716  );
2717  $fh = @call_user_func_array('fopen', $args);
2718  restore_error_handler();
2719  if ($fh !== FALSE) {
2720  return $fh;
2721  }
2722  return $errors;
2723 }
2724 ?>
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:2423
get_random_char()
Returns a random char.
Definition: functions.inc:2401
const FD_VERSION
FusionDirectory Version.
rmdirRecursive($path, $followLinks=FALSE)
Recursively delete a path in the file system.
Definition: functions.inc:1718
const CLASS_CACHE
name of the class.cache file
Definition: variables.inc:85
eval_sizelimit()
Handle sizelimit dialog related posts.
Definition: functions.inc:889
in_array_ics($value, array $items)
Check if a value exists in an array (case-insensitive)
Definition: functions.inc:1657
get_lock($object)
Get a lock for a specific object.
Definition: functions.inc:745
normalize_netmask($netmask)
Put netmask in n.n.n.n format.
Definition: functions.inc:1383
array_differs_recursive($src, $dst)
Determine if two arrays are different using recursion for sublevels.
Definition: functions.inc:1940
get_ou($name)
Get the OU of a certain RDN.
Definition: functions.inc:1001
compare_revision($revision_file, $revision)
Compare the revision file.
Definition: functions.inc:1859
check_sizelimit()
Show sizelimit configuration dialog.
Definition: functions.inc:846
This class contains all function to manage ldap multiplexer.
get_browser_language()
Determine which language to show to the user.
Definition: functions.inc:246
gen_uids($rule, $attributes)
Generate a list of uid proposals based on a rule.
Definition: functions.inc:1491
del_user_locks($userdn)
Remove all locks owned by a specific userdn.
Definition: functions.inc:719
get_languages($languages_in_own_language=FALSE, $strip_region_tag=FALSE)
Get the language for the user connecting.
Definition: functions.inc:2091
scan_directory($path, $sort_desc=FALSE)
Get directory content information.
Definition: functions.inc:1745
send_binary_content($data, $name, $type="application/octet-stream")
Initialize a file download with given content, name and data type.
Definition: functions.inc:2341
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:922
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:670
__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:296
ldap_get_user($username)
Get user from LDAP directory.
Definition: functions.inc:475
fusiondirectory_log($message)
Generate a system log info.
Definition: functions.inc:410
array_merge_unique($ar1, $ar2)
Merge to array but remove duplicate entries (case-insensitive)
Definition: functions.inc:393
get_correct_class_name($cls)
Return class name in correct case.
Definition: functions.inc:2204
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:1111
ldap_init($server, $base, $binddn= '', $pass= '')
Initialize a LDAP connection.
Definition: functions.inc:445
static & get($name)
Accessor of a session.
_recurse_gen_uids($rule, $variables)
Recursion helper for gen_uids()
Definition: functions.inc:1457
& get_smarty()
Get global smarty object.
Definition: functions.inc:934
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:2469
ldap_login_user($username, $password)
Verify user login against LDAP directory.
Definition: functions.inc:547
getEntryCSN($dn)
Get the Change Sequence Number of a certain DN.
Definition: functions.inc:2312
netmask_to_bits($netmask)
Return the number of set bits in the netmask.
Definition: functions.inc:1433
language_is_rtl($lang)
Returns TRUE if $lang is a right to left language ($lang should match /.._..(.UTF-8)?/)
Definition: functions.inc:2170
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:1979
Parent class for all exceptions thrown in FusionDirectory.
to_string($value)
Return a string/HTML representation of an array.
Definition: functions.inc:1252
dn2base($dn, $ou=NULL)
Return the base of a given DN.
Definition: functions.inc:1295
change_password($dn, $password, $hash="")
Change the password of a given DN.
Definition: functions.inc:2232
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:1831
Class userinfo This class contains all informations and functions about user.
generate_alphabet($count=10)
Generate a clickable alphabet.
Definition: functions.inc:1664
rewrite($s)
Function to rewrite some problematic characters.
Definition: functions.inc:1275
gen_locked_message($locks, $dn, $allow_readonly=FALSE)
Generate a lock message.
Definition: functions.inc:1170
xmlentities($str)
Encode special string characters.
Definition: functions.inc:2386
validate($string)
Removes malicious characters from a (POST) string.
Definition: functions.inc:1702
get_locks($objects, $allow_readonly=FALSE)
Get locks for objects.
Definition: functions.inc:782
DEBUG($level, $line, $function, $file, $data, $info= '')
Debug level action.
Definition: functions.inc:200
array_differs($src, $dst)
Determine if two arrays are different.
Definition: functions.inc:1921
initLanguage($lang=NULL)
Definition: functions.inc:2530
strict_uid_mode()
Check if strict naming rules are configured.
Definition: functions.inc:1136
array_key_ics($ikey, array $items)
Lookup a key in an array case-insensitive.
Definition: functions.inc:1900
print_header($image, $headline, $info= '')
Print plugin HTML header.
Definition: functions.inc:1349
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:1095
check_command($cmdline)
Check if a given command exists and is executable.
Definition: functions.inc:1321
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:2191
static global_get($name)
Accessor of a session var.
expandIPv6($ip)
Expands an IP v6.
Definition: functions.inc:2483
clean_smarty_compile_dir($directory)
Clean the smarty compile dir.
Definition: functions.inc:1785
normalizeLdap($input)
Escape all LDAP filter relevant characters.
Definition: functions.inc:1968
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:959
to_byte($value)
Convert various data sizes to bytes.
Definition: functions.inc:1590
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:375
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:359
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:1370
add_lock($object, $user)
Add a lock for object(s)
Definition: functions.inc:600
print_sizelimit_warning()
Print a sizelimit warning.
Definition: functions.inc:871
humanReadableSize($bytes, $precision=2)
Convert a size in bytes to a human readable version.
Definition: functions.inc:1623
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.