dolibarr  17.0.3
security.lib.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (C) 2008-2021 Laurent Destailleur <eldy@users.sourceforge.net>
3  * Copyright (C) 2008-2021 Regis Houssin <regis.houssin@inodbox.com>
4  * Copyright (C) 2020 Ferran Marcet <fmarcet@2byte.es>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program. If not, see <https://www.gnu.org/licenses/>.
18  * or see https://www.gnu.org/
19  */
20 
38 function dol_encode($chain, $key = '1')
39 {
40  if (is_numeric($key) && $key == '1') { // rule 1 is offset of 17 for char
41  $output_tab = array();
42  $strlength = dol_strlen($chain);
43  for ($i = 0; $i < $strlength; $i++) {
44  $output_tab[$i] = chr(ord(substr($chain, $i, 1)) + 17);
45  }
46  $chain = implode("", $output_tab);
47  } elseif ($key) {
48  $result = '';
49  $strlength = dol_strlen($chain);
50  for ($i = 0; $i < $strlength; $i++) {
51  $keychar = substr($key, ($i % strlen($key)) - 1, 1);
52  $result .= chr(ord(substr($chain, $i, 1)) + (ord($keychar) - 65));
53  }
54  $chain = $result;
55  }
56 
57  return base64_encode($chain);
58 }
59 
69 function dol_decode($chain, $key = '1')
70 {
71  $chain = base64_decode($chain);
72 
73  if (is_numeric($key) && $key == '1') { // rule 1 is offset of 17 for char
74  $output_tab = array();
75  $strlength = dol_strlen($chain);
76  for ($i = 0; $i < $strlength; $i++) {
77  $output_tab[$i] = chr(ord(substr($chain, $i, 1)) - 17);
78  }
79 
80  $chain = implode("", $output_tab);
81  } elseif ($key) {
82  $result = '';
83  $strlength = dol_strlen($chain);
84  for ($i = 0; $i < $strlength; $i++) {
85  $keychar = substr($key, ($i % strlen($key)) - 1, 1);
86  $result .= chr(ord(substr($chain, $i, 1)) - (ord($keychar) - 65));
87  }
88  $chain = $result;
89  }
90 
91  return $chain;
92 }
93 
100 function dolGetRandomBytes($length)
101 {
102  if (function_exists('random_bytes')) { // Available with PHP 7 only.
103  return bin2hex(random_bytes((int) floor($length / 2))); // the bin2hex will double the number of bytes so we take length / 2
104  }
105 
106  return bin2hex(openssl_random_pseudo_bytes((int) floor($length / 2))); // the bin2hex will double the number of bytes so we take length / 2. May be very slow on Windows.
107 }
108 
120 function dolEncrypt($chain, $key = '', $ciphering = 'AES-256-CTR', $forceseed = '')
121 {
122  global $dolibarr_main_instance_unique_id;
123  global $dolibarr_disable_dolcrypt_for_debug;
124 
125  if ($chain === '' || is_null($chain)) {
126  return '';
127  }
128 
129  $reg = array();
130  if (preg_match('/^dolcrypt:([^:]+):(.+)$/', $chain, $reg)) {
131  // The $chain is already a crypted string
132  return $chain;
133  }
134 
135  if (empty($key)) {
136  $key = $dolibarr_main_instance_unique_id;
137  }
138  if (empty($ciphering)) {
139  $ciphering = 'AES-256-CTR';
140  }
141 
142  $newchain = $chain;
143 
144  if (function_exists('openssl_encrypt') && empty($dolibarr_disable_dolcrypt_for_debug)) {
145  $ivlen = 16;
146  if (function_exists('openssl_cipher_iv_length')) {
147  $ivlen = openssl_cipher_iv_length($ciphering);
148  }
149  if ($ivlen === false || $ivlen < 1 || $ivlen > 32) {
150  $ivlen = 16;
151  }
152  if (empty($forceseed)) {
153  $ivseed = dolGetRandomBytes($ivlen);
154  } else {
155  $ivseed = dol_substr(md5($forceseed), 0, $ivlen, 'ascii', 1);
156  }
157 
158  $newchain = openssl_encrypt($chain, $ciphering, $key, 0, $ivseed);
159  return 'dolcrypt:'.$ciphering.':'.$ivseed.':'.$newchain;
160  } else {
161  return $chain;
162  }
163 }
164 
174 function dolDecrypt($chain, $key = '')
175 {
176  global $dolibarr_main_instance_unique_id;
177 
178  if ($chain === '' || is_null($chain)) {
179  return '';
180  }
181 
182  if (empty($key)) {
183  $key = $dolibarr_main_instance_unique_id;
184  }
185 
186  $reg = array();
187  if (preg_match('/^dolcrypt:([^:]+):(.+)$/', $chain, $reg)) {
188  $ciphering = $reg[1];
189  if (function_exists('openssl_decrypt')) {
190  $tmpexplode = explode(':', $reg[2]);
191  if (!empty($tmpexplode[1]) && is_string($tmpexplode[0])) {
192  $newchain = openssl_decrypt($tmpexplode[1], $ciphering, $key, 0, $tmpexplode[0]);
193  } else {
194  $newchain = openssl_decrypt($tmpexplode[0], $ciphering, $key, 0, null);
195  }
196  } else {
197  $newchain = 'Error function openssl_decrypt() not available';
198  }
199  return $newchain;
200  } else {
201  return $chain;
202  }
203 }
204 
215 function dol_hash($chain, $type = '0')
216 {
217  global $conf;
218 
219  // No need to add salt for password_hash
220  if (($type == '0' || $type == 'auto') && !empty($conf->global->MAIN_SECURITY_HASH_ALGO) && $conf->global->MAIN_SECURITY_HASH_ALGO == 'password_hash' && function_exists('password_hash')) {
221  return password_hash($chain, PASSWORD_DEFAULT);
222  }
223 
224  // Salt value
225  if (!empty($conf->global->MAIN_SECURITY_SALT) && $type != '4' && $type !== 'openldap') {
226  $chain = $conf->global->MAIN_SECURITY_SALT.$chain;
227  }
228 
229  if ($type == '1' || $type == 'sha1') {
230  return sha1($chain);
231  } elseif ($type == '2' || $type == 'sha1md5') {
232  return sha1(md5($chain));
233  } elseif ($type == '3' || $type == 'md5') {
234  return md5($chain);
235  } elseif ($type == '4' || $type == 'openldap') {
236  return dolGetLdapPasswordHash($chain, getDolGlobalString('LDAP_PASSWORD_HASH_TYPE', 'md5'));
237  } elseif ($type == '5' || $type == 'sha256') {
238  return hash('sha256', $chain);
239  } elseif ($type == '6' || $type == 'password_hash') {
240  return password_hash($chain, PASSWORD_DEFAULT);
241  } elseif (!empty($conf->global->MAIN_SECURITY_HASH_ALGO) && $conf->global->MAIN_SECURITY_HASH_ALGO == 'sha1') {
242  return sha1($chain);
243  } elseif (!empty($conf->global->MAIN_SECURITY_HASH_ALGO) && $conf->global->MAIN_SECURITY_HASH_ALGO == 'sha1md5') {
244  return sha1(md5($chain));
245  }
246 
247  // No particular encoding defined, use default
248  return md5($chain);
249 }
250 
263 function dol_verifyHash($chain, $hash, $type = '0')
264 {
265  global $conf;
266 
267  if ($type == '0' && !empty($conf->global->MAIN_SECURITY_HASH_ALGO) && $conf->global->MAIN_SECURITY_HASH_ALGO == 'password_hash' && function_exists('password_verify')) {
268  if (! empty($hash[0]) && $hash[0] == '$') {
269  return password_verify($chain, $hash);
270  } elseif (dol_strlen($hash) == 32) {
271  return dol_verifyHash($chain, $hash, '3'); // md5
272  } elseif (dol_strlen($hash) == 40) {
273  return dol_verifyHash($chain, $hash, '2'); // sha1md5
274  }
275 
276  return false;
277  }
278 
279  return dol_hash($chain, $type) == $hash;
280 }
281 
289 function dolGetLdapPasswordHash($password, $type = 'md5')
290 {
291  if (empty($type)) {
292  $type = 'md5';
293  }
294 
295  $salt = substr(sha1(time()), 0, 8);
296 
297  if ($type === 'md5') {
298  return '{MD5}' . base64_encode(hash("md5", $password, true)); //For OpenLdap with md5 (based on an unencrypted password in base)
299  } elseif ($type === 'md5frommd5') {
300  return '{MD5}' . base64_encode(hex2bin($password)); // Create OpenLDAP MD5 password from Dolibarr MD5 password
301  } elseif ($type === 'smd5') {
302  return "{SMD5}" . base64_encode(hash("md5", $password . $salt, true) . $salt);
303  } elseif ($type === 'sha') {
304  return '{SHA}' . base64_encode(hash("sha1", $password, true));
305  } elseif ($type === 'ssha') {
306  return "{SSHA}" . base64_encode(hash("sha1", $password . $salt, true) . $salt);
307  } elseif ($type === 'sha256') {
308  return "{SHA256}" . base64_encode(hash("sha256", $password, true));
309  } elseif ($type === 'ssha256') {
310  return "{SSHA256}" . base64_encode(hash("sha256", $password . $salt, true) . $salt);
311  } elseif ($type === 'sha384') {
312  return "{SHA384}" . base64_encode(hash("sha384", $password, true));
313  } elseif ($type === 'ssha384') {
314  return "{SSHA384}" . base64_encode(hash("sha384", $password . $salt, true) . $salt);
315  } elseif ($type === 'sha512') {
316  return "{SHA512}" . base64_encode(hash("sha512", $password, true));
317  } elseif ($type === 'ssha512') {
318  return "{SSHA512}" . base64_encode(hash("sha512", $password . $salt, true) . $salt);
319  } elseif ($type === 'crypt') {
320  return '{CRYPT}' . crypt($password, $salt);
321  } elseif ($type === 'clear') {
322  return '{CLEAR}' . $password; // Just for test, plain text password is not secured !
323  }
324 }
325 
346 function restrictedArea(User $user, $features, $object = 0, $tableandshare = '', $feature2 = '', $dbt_keyfield = 'fk_soc', $dbt_select = 'rowid', $isdraft = 0, $mode = 0)
347 {
348  global $db, $conf;
349  global $hookmanager;
350 
351  if (is_object($object)) {
352  $objectid = $object->id;
353  } else {
354  $objectid = $object; // $objectid can be X or 'X,Y,Z'
355  }
356  if ($objectid == "-1") {
357  $objectid = 0;
358  }
359  if ($objectid) {
360  $objectid = preg_replace('/[^0-9\.\,]/', '', $objectid); // For the case value is coming from a non sanitized user input
361  }
362 
363  //dol_syslog("functions.lib:restrictedArea $feature, $objectid, $dbtablename, $feature2, $dbt_socfield, $dbt_select, $isdraft");
364  //print "user_id=".$user->id.", features=".$features.", feature2=".$feature2.", objectid=".$objectid;
365  //print ", dbtablename=".$tableandshare.", dbt_socfield=".$dbt_keyfield.", dbt_select=".$dbt_select;
366  //print ", perm: ".$features."->".$feature2."=".($user->rights->$features->$feature2->lire)."<br>";
367 
368  $parentfortableentity = '';
369 
370  // Fix syntax of $features param
371  $originalfeatures = $features;
372  if ($features == 'facturerec') {
373  $features = 'facture';
374  }
375  if ($features == 'mo') {
376  $features = 'mrp';
377  }
378  if ($features == 'member') {
379  $features = 'adherent';
380  }
381  if ($features == 'subscription') {
382  $features = 'adherent';
383  $feature2 = 'cotisation';
384  };
385  if ($features == 'websitepage') {
386  $features = 'website';
387  $tableandshare = 'website_page';
388  $parentfortableentity = 'fk_website@website';
389  }
390  if ($features == 'project') {
391  $features = 'projet';
392  }
393  if ($features == 'product') {
394  $features = 'produit';
395  }
396 
397  // Get more permissions checks from hooks
398  $parameters = array('features'=>$features, 'originalfeatures'=>$originalfeatures, 'objectid'=>$objectid, 'dbt_select'=>$dbt_select, 'idtype'=>$dbt_select, 'isdraft'=>$isdraft);
399  $reshook = $hookmanager->executeHooks('restrictedArea', $parameters);
400 
401  if (isset($hookmanager->resArray['result'])) {
402  if ($hookmanager->resArray['result'] == 0) {
403  if ($mode) {
404  return 0;
405  } else {
406  accessforbidden(); // Module returns 0, so access forbidden
407  }
408  }
409  }
410  if ($reshook > 0) { // No other test done.
411  return 1;
412  }
413 
414  // Features/modules to check
415  $featuresarray = array($features);
416  if (preg_match('/&/', $features)) {
417  $featuresarray = explode("&", $features);
418  } elseif (preg_match('/\|/', $features)) {
419  $featuresarray = explode("|", $features);
420  }
421 
422  // More subfeatures to check
423  if (!empty($feature2)) {
424  $feature2 = explode("|", $feature2);
425  }
426 
427  $listofmodules = explode(',', $conf->global->MAIN_MODULES_FOR_EXTERNAL);
428 
429  // Check read permission from module
430  $readok = 1;
431  $nbko = 0;
432  foreach ($featuresarray as $feature) { // first we check nb of test ko
433  $featureforlistofmodule = $feature;
434  if ($featureforlistofmodule == 'produit') {
435  $featureforlistofmodule = 'product';
436  }
437  if ($featureforlistofmodule == 'supplier_proposal') {
438  $featureforlistofmodule = 'supplierproposal';
439  }
440  if (!empty($user->socid) && !empty($conf->global->MAIN_MODULES_FOR_EXTERNAL) && !in_array($featureforlistofmodule, $listofmodules)) { // If limits on modules for external users, module must be into list of modules for external users
441  $readok = 0;
442  $nbko++;
443  continue;
444  }
445 
446  if ($feature == 'societe') {
447  if (!$user->hasRight('societe', 'lire') && !$user->hasRight('fournisseur', 'lire')) {
448  $readok = 0;
449  $nbko++;
450  }
451  } elseif ($feature == 'contact') {
452  if (empty($user->rights->societe->contact->lire)) {
453  $readok = 0;
454  $nbko++;
455  }
456  } elseif ($feature == 'produit|service') {
457  if (empty($user->rights->produit->lire) && empty($user->rights->service->lire)) {
458  $readok = 0;
459  $nbko++;
460  }
461  } elseif ($feature == 'prelevement') {
462  if (empty($user->rights->prelevement->bons->lire)) {
463  $readok = 0;
464  $nbko++;
465  }
466  } elseif ($feature == 'cheque') {
467  if (empty($user->rights->banque->cheque)) {
468  $readok = 0;
469  $nbko++;
470  }
471  } elseif ($feature == 'projet') {
472  if (empty($user->rights->projet->lire) && empty($user->rights->projet->all->lire)) {
473  $readok = 0;
474  $nbko++;
475  }
476  } elseif ($feature == 'payment') {
477  if (empty($user->rights->facture->lire)) {
478  $readok = 0;
479  $nbko++;
480  }
481  } elseif ($feature == 'payment_supplier') {
482  if (empty($user->rights->fournisseur->facture->lire)) {
483  $readok = 0;
484  $nbko++;
485  }
486  } elseif ($feature == 'payment_sc') {
487  if (empty($user->rights->tax->charges->lire)) {
488  $readok = 0;
489  $nbko++;
490  }
491  } elseif (!empty($feature2)) { // This is for permissions on 2 levels
492  $tmpreadok = 1;
493  foreach ($feature2 as $subfeature) {
494  if ($subfeature == 'user' && $user->id == $objectid) {
495  continue; // A user can always read its own card
496  }
497  if (!empty($subfeature) && empty($user->rights->$feature->$subfeature->lire) && empty($user->rights->$feature->$subfeature->read)) {
498  $tmpreadok = 0;
499  } elseif (empty($subfeature) && empty($user->rights->$feature->lire) && empty($user->rights->$feature->read)) {
500  $tmpreadok = 0;
501  } else {
502  $tmpreadok = 1;
503  break;
504  } // Break is to bypass second test if the first is ok
505  }
506  if (!$tmpreadok) { // We found a test on feature that is ko
507  $readok = 0; // All tests are ko (we manage here the and, the or will be managed later using $nbko).
508  $nbko++;
509  }
510  } elseif (!empty($feature) && ($feature != 'user' && $feature != 'usergroup')) { // This is permissions on 1 level
511  if (empty($user->rights->$feature->lire)
512  && empty($user->rights->$feature->read)
513  && empty($user->rights->$feature->run)) {
514  $readok = 0;
515  $nbko++;
516  }
517  }
518  }
519 
520  // If a or and at least one ok
521  if (preg_match('/\|/', $features) && $nbko < count($featuresarray)) {
522  $readok = 1;
523  }
524 
525  if (!$readok) {
526  if ($mode) {
527  return 0;
528  } else {
529  accessforbidden();
530  }
531  }
532  //print "Read access is ok";
533 
534  // Check write permission from module (we need to know write permission to create but also to delete drafts record or to upload files)
535  $createok = 1;
536  $nbko = 0;
537  $wemustcheckpermissionforcreate = (GETPOST('sendit', 'alpha') || GETPOST('linkit', 'alpha') || in_array(GETPOST('action', 'aZ09'), array('create', 'update', 'add_element_resource', 'confirm_deletebank', 'confirm_delete_linked_resource')) || GETPOST('roworder', 'alpha', 2));
538  $wemustcheckpermissionfordeletedraft = ((GETPOST("action", "aZ09") == 'confirm_delete' && GETPOST("confirm", "aZ09") == 'yes') || GETPOST("action", "aZ09") == 'delete');
539 
540  if ($wemustcheckpermissionforcreate || $wemustcheckpermissionfordeletedraft) {
541  foreach ($featuresarray as $feature) {
542  if ($feature == 'contact') {
543  if (empty($user->rights->societe->contact->creer)) {
544  $createok = 0;
545  $nbko++;
546  }
547  } elseif ($feature == 'produit|service') {
548  if (empty($user->rights->produit->creer) && empty($user->rights->service->creer)) {
549  $createok = 0;
550  $nbko++;
551  }
552  } elseif ($feature == 'prelevement') {
553  if (!$user->rights->prelevement->bons->creer) {
554  $createok = 0;
555  $nbko++;
556  }
557  } elseif ($feature == 'commande_fournisseur') {
558  if (empty($user->rights->fournisseur->commande->creer) || empty($user->rights->supplier_order->creer)) {
559  $createok = 0;
560  $nbko++;
561  }
562  } elseif ($feature == 'banque') {
563  if (empty($user->rights->banque->modifier)) {
564  $createok = 0;
565  $nbko++;
566  }
567  } elseif ($feature == 'cheque') {
568  if (empty($user->rights->banque->cheque)) {
569  $createok = 0;
570  $nbko++;
571  }
572  } elseif ($feature == 'import') {
573  if (empty($user->rights->import->run)) {
574  $createok = 0;
575  $nbko++;
576  }
577  } elseif ($feature == 'ecm') {
578  if (!$user->rights->ecm->upload) {
579  $createok = 0;
580  $nbko++;
581  }
582  } elseif (!empty($feature2)) { // This is for permissions on one level
583  foreach ($feature2 as $subfeature) {
584  if ($subfeature == 'user' && $user->id == $objectid && $user->rights->user->self->creer) {
585  continue; // User can edit its own card
586  }
587  if ($subfeature == 'user' && $user->id == $objectid && $user->rights->user->self->password) {
588  continue; // User can edit its own password
589  }
590  if ($subfeature == 'user' && $user->id != $objectid && $user->rights->user->user->password) {
591  continue; // User can edit another user's password
592  }
593 
594  if (empty($user->rights->$feature->$subfeature->creer)
595  && empty($user->rights->$feature->$subfeature->write)
596  && empty($user->rights->$feature->$subfeature->create)) {
597  $createok = 0;
598  $nbko++;
599  } else {
600  $createok = 1;
601  // Break to bypass second test if the first is ok
602  break;
603  }
604  }
605  } elseif (!empty($feature)) { // This is for permissions on 2 levels ('creer' or 'write')
606  //print '<br>feature='.$feature.' creer='.$user->rights->$feature->creer.' write='.$user->rights->$feature->write; exit;
607  if (empty($user->rights->$feature->creer)
608  && empty($user->rights->$feature->write)
609  && empty($user->rights->$feature->create)) {
610  $createok = 0;
611  $nbko++;
612  }
613  }
614  }
615 
616  // If a or and at least one ok
617  if (preg_match('/\|/', $features) && $nbko < count($featuresarray)) {
618  $createok = 1;
619  }
620 
621  if ($wemustcheckpermissionforcreate && !$createok) {
622  if ($mode) {
623  return 0;
624  } else {
625  accessforbidden();
626  }
627  }
628  //print "Write access is ok";
629  }
630 
631  // Check create user permission
632  $createuserok = 1;
633  if (GETPOST('action', 'aZ09') == 'confirm_create_user' && GETPOST("confirm", 'aZ09') == 'yes') {
634  if (!$user->rights->user->user->creer) {
635  $createuserok = 0;
636  }
637 
638  if (!$createuserok) {
639  if ($mode) {
640  return 0;
641  } else {
642  accessforbidden();
643  }
644  }
645  //print "Create user access is ok";
646  }
647 
648  // Check delete permission from module
649  $deleteok = 1;
650  $nbko = 0;
651  if ((GETPOST("action", "aZ09") == 'confirm_delete' && GETPOST("confirm", "aZ09") == 'yes') || GETPOST("action", "aZ09") == 'delete') {
652  foreach ($featuresarray as $feature) {
653  if ($feature == 'bookmark') {
654  if (!$user->rights->bookmark->supprimer) {
655  if ($user->id != $object->fk_user || empty($user->rights->bookmark->creer)) {
656  $deleteok = 0;
657  }
658  }
659  } elseif ($feature == 'contact') {
660  if (!$user->rights->societe->contact->supprimer) {
661  $deleteok = 0;
662  }
663  } elseif ($feature == 'produit|service') {
664  if (!$user->rights->produit->supprimer && !$user->rights->service->supprimer) {
665  $deleteok = 0;
666  }
667  } elseif ($feature == 'commande_fournisseur') {
668  if (!$user->rights->fournisseur->commande->supprimer) {
669  $deleteok = 0;
670  }
671  } elseif ($feature == 'payment_supplier') { // Permission to delete a payment of an invoice is permission to edit an invoice.
672  if (!$user->rights->fournisseur->facture->creer) {
673  $deleteok = 0;
674  }
675  } elseif ($feature == 'payment') {
676  if (!$user->rights->facture->paiement) {
677  $deleteok = 0;
678  }
679  } elseif ($feature == 'payment_sc') {
680  if (!$user->rights->tax->charges->creer) {
681  $deleteok = 0;
682  }
683  } elseif ($feature == 'banque') {
684  if (empty($user->rights->banque->modifier)) {
685  $deleteok = 0;
686  }
687  } elseif ($feature == 'cheque') {
688  if (empty($user->rights->banque->cheque)) {
689  $deleteok = 0;
690  }
691  } elseif ($feature == 'ecm') {
692  if (!$user->rights->ecm->upload) {
693  $deleteok = 0;
694  }
695  } elseif ($feature == 'ftp') {
696  if (!$user->rights->ftp->write) {
697  $deleteok = 0;
698  }
699  } elseif ($feature == 'salaries') {
700  if (!$user->rights->salaries->delete) {
701  $deleteok = 0;
702  }
703  } elseif ($feature == 'adherent') {
704  if (empty($user->rights->adherent->supprimer)) {
705  $deleteok = 0;
706  }
707  } elseif ($feature == 'paymentbybanktransfer') {
708  if (empty($user->rights->paymentbybanktransfer->create)) { // There is no delete permission
709  $deleteok = 0;
710  }
711  } elseif ($feature == 'prelevement') {
712  if (empty($user->rights->prelevement->bons->creer)) { // There is no delete permission
713  $deleteok = 0;
714  }
715  } elseif (!empty($feature2)) { // This is for permissions on 2 levels
716  foreach ($feature2 as $subfeature) {
717  if (empty($user->rights->$feature->$subfeature->supprimer) && empty($user->rights->$feature->$subfeature->delete)) {
718  $deleteok = 0;
719  } else {
720  $deleteok = 1;
721  break;
722  } // For bypass the second test if the first is ok
723  }
724  } elseif (!empty($feature)) { // This is used for permissions on 1 level
725  //print '<br>feature='.$feature.' creer='.$user->rights->$feature->supprimer.' write='.$user->rights->$feature->delete;
726  if (empty($user->rights->$feature->supprimer)
727  && empty($user->rights->$feature->delete)
728  && empty($user->rights->$feature->run)) {
729  $deleteok = 0;
730  }
731  }
732  }
733 
734  // If a or and at least one ok
735  if (preg_match('/\|/', $features) && $nbko < count($featuresarray)) {
736  $deleteok = 1;
737  }
738 
739  if (!$deleteok && !($isdraft && $createok)) {
740  if ($mode) {
741  return 0;
742  } else {
743  accessforbidden();
744  }
745  }
746  //print "Delete access is ok";
747  }
748 
749  // If we have a particular object to check permissions on, we check if $user has permission
750  // for this given object (link to company, is contact for project, ...)
751  if (!empty($objectid) && $objectid > 0) {
752  $ok = checkUserAccessToObject($user, $featuresarray, $object, $tableandshare, $feature2, $dbt_keyfield, $dbt_select, $parentfortableentity);
753  $params = array('objectid' => $objectid, 'features' => join(',', $featuresarray), 'features2' => $feature2);
754  //print 'checkUserAccessToObject ok='.$ok;
755  if ($mode) {
756  return $ok ? 1 : 0;
757  } else {
758  if ($ok) {
759  return 1;
760  } else {
761  accessforbidden('', 1, 1, 0, $params);
762  }
763  }
764  }
765 
766  return 1;
767 }
768 
784 function checkUserAccessToObject($user, array $featuresarray, $object = 0, $tableandshare = '', $feature2 = '', $dbt_keyfield = '', $dbt_select = 'rowid', $parenttableforentity = '')
785 {
786  global $db, $conf;
787 
788  if (is_object($object)) {
789  $objectid = $object->id;
790  } else {
791  $objectid = $object; // $objectid can be X or 'X,Y,Z'
792  }
793  $objectid = preg_replace('/[^0-9\.\,]/', '', $objectid); // For the case value is coming from a non sanitized user input
794 
795  //dol_syslog("functions.lib:restrictedArea $feature, $objectid, $dbtablename, $feature2, $dbt_socfield, $dbt_select, $isdraft");
796  //print "user_id=".$user->id.", features=".join(',', $featuresarray).", objectid=".$objectid;
797  //print ", tableandshare=".$tableandshare.", dbt_socfield=".$dbt_keyfield.", dbt_select=".$dbt_select."<br>";
798 
799  // More parameters
800  $params = explode('&', $tableandshare);
801  $dbtablename = (!empty($params[0]) ? $params[0] : '');
802  $sharedelement = (!empty($params[1]) ? $params[1] : $dbtablename);
803 
804  foreach ($featuresarray as $feature) {
805  $sql = '';
806 
807  //var_dump($feature);exit;
808 
809  // For backward compatibility
810  if ($feature == 'member') {
811  $feature = 'adherent';
812  }
813  if ($feature == 'project') {
814  $feature = 'projet';
815  }
816  if ($feature == 'task') {
817  $feature = 'projet_task';
818  }
819 
820  if ($feature == 'payment_sc') {
821  $feature = "chargesociales";
822  }
823  $checkonentitydone = 0;
824 
825  // Array to define rules of checks to do
826  $check = array('adherent', 'banque', 'bom', 'don', 'mrp', 'user', 'usergroup', 'payment', 'payment_supplier', 'product', 'produit', 'service', 'produit|service', 'categorie', 'resource', 'expensereport', 'holiday', 'salaries', 'website', 'recruitment','chargesociales'); // Test on entity only (Objects with no link to company)
827  $checksoc = array('societe'); // Test for object Societe
828  $checkother = array('contact', 'agenda', 'contrat'); // Test on entity + link to third party on field $dbt_keyfield. Allowed if link is empty (Ex: contacts...).
829  $checkproject = array('projet', 'project'); // Test for project object
830  $checktask = array('projet_task'); // Test for task object
831  $checkhierarchy = array('expensereport', 'holiday'); // check permission among the hierarchy of user
832  $checkuser = array('bookmark'); // check permission among the fk_user (must be myself or null)
833  $nocheck = array('barcode', 'stock'); // No test
834 
835  //$checkdefault = 'all other not already defined'; // Test on entity + link to third party on field $dbt_keyfield. Not allowed if link is empty (Ex: invoice, orders...).
836 
837  // If dbtablename not defined, we use same name for table than module name
838  if (empty($dbtablename)) {
839  $dbtablename = $feature;
840  $sharedelement = (!empty($params[1]) ? $params[1] : $dbtablename); // We change dbtablename, so we set sharedelement too.
841  }
842 
843  // To avoid an access forbidden with a numeric ref
844  if ($dbt_select != 'rowid' && $dbt_select != 'id') {
845  $objectid = "'".$objectid."'"; // Note: $objectid was already cast into int at begin of this method.
846  }
847 
848  // Check permission for objectid on entity only
849  if (in_array($feature, $check) && $objectid > 0) { // For $objectid = 0, no check
850  $sql = "SELECT COUNT(dbt.".$dbt_select.") as nb";
851  $sql .= " FROM ".MAIN_DB_PREFIX.$dbtablename." as dbt";
852  if (($feature == 'user' || $feature == 'usergroup') && isModEnabled('multicompany')) { // Special for multicompany
853  if (!empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) {
854  if ($conf->entity == 1 && $user->admin && !$user->entity) {
855  $sql .= " WHERE dbt.".$dbt_select." IN (".$db->sanitize($objectid, 1).")";
856  $sql .= " AND dbt.entity IS NOT NULL";
857  } else {
858  $sql .= ",".MAIN_DB_PREFIX."usergroup_user as ug";
859  $sql .= " WHERE dbt.".$dbt_select." IN (".$db->sanitize($objectid, 1).")";
860  $sql .= " AND ((ug.fk_user = dbt.rowid";
861  $sql .= " AND ug.entity IN (".getEntity('usergroup')."))";
862  $sql .= " OR dbt.entity = 0)"; // Show always superadmin
863  }
864  } else {
865  $sql .= " WHERE dbt.".$dbt_select." IN (".$db->sanitize($objectid, 1).")";
866  $sql .= " AND dbt.entity IN (".getEntity($sharedelement, 1).")";
867  }
868  } else {
869  $reg = array();
870  if ($parenttableforentity && preg_match('/(.*)@(.*)/', $parenttableforentity, $reg)) {
871  $sql .= ", ".MAIN_DB_PREFIX.$reg[2]." as dbtp";
872  $sql .= " WHERE dbt.".$reg[1]." = dbtp.rowid AND dbt.".$dbt_select." IN (".$db->sanitize($objectid, 1).")";
873  $sql .= " AND dbtp.entity IN (".getEntity($sharedelement, 1).")";
874  } else {
875  $sql .= " WHERE dbt.".$dbt_select." IN (".$db->sanitize($objectid, 1).")";
876  $sql .= " AND dbt.entity IN (".getEntity($sharedelement, 1).")";
877  }
878  }
879  $checkonentitydone = 1;
880  }
881  if (in_array($feature, $checksoc) && $objectid > 0) { // We check feature = checksoc. For $objectid = 0, no check
882  // If external user: Check permission for external users
883  if ($user->socid > 0) {
884  if ($user->socid != $objectid) {
885  return false;
886  }
887  } elseif (isModEnabled("societe") && ($user->hasRight('societe', 'lire') && empty($user->rights->societe->client->voir))) {
888  // If internal user: Check permission for internal users that are restricted on their objects
889  $sql = "SELECT COUNT(sc.fk_soc) as nb";
890  $sql .= " FROM (".MAIN_DB_PREFIX."societe_commerciaux as sc";
891  $sql .= ", ".MAIN_DB_PREFIX."societe as s)";
892  $sql .= " WHERE sc.fk_soc IN (".$db->sanitize($objectid, 1).")";
893  $sql .= " AND sc.fk_user = ".((int) $user->id);
894  $sql .= " AND sc.fk_soc = s.rowid";
895  $sql .= " AND s.entity IN (".getEntity($sharedelement, 1).")";
896  } elseif (isModEnabled('multicompany')) {
897  // If multicompany and internal users with all permissions, check user is in correct entity
898  $sql = "SELECT COUNT(s.rowid) as nb";
899  $sql .= " FROM ".MAIN_DB_PREFIX."societe as s";
900  $sql .= " WHERE s.rowid IN (".$db->sanitize($objectid, 1).")";
901  $sql .= " AND s.entity IN (".getEntity($sharedelement, 1).")";
902  }
903 
904  $checkonentitydone = 1;
905  }
906  if (in_array($feature, $checkother) && $objectid > 0) { // Test on entity + link to thirdparty. Allowed if link is empty (Ex: contacts...).
907  // If external user: Check permission for external users
908  if ($user->socid > 0) {
909  $sql = "SELECT COUNT(dbt.".$dbt_select.") as nb";
910  $sql .= " FROM ".MAIN_DB_PREFIX.$dbtablename." as dbt";
911  $sql .= " WHERE dbt.".$dbt_select." IN (".$db->sanitize($objectid, 1).")";
912  $sql .= " AND dbt.fk_soc = ".((int) $user->socid);
913  } elseif (isModEnabled("societe") && ($user->hasRight('societe', 'lire') && empty($user->rights->societe->client->voir))) {
914  // If internal user: Check permission for internal users that are restricted on their objects
915  $sql = "SELECT COUNT(dbt.".$dbt_select.") as nb";
916  $sql .= " FROM ".MAIN_DB_PREFIX.$dbtablename." as dbt";
917  $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON dbt.fk_soc = sc.fk_soc AND sc.fk_user = ".((int) $user->id);
918  $sql .= " WHERE dbt.".$dbt_select." IN (".$db->sanitize($objectid, 1).")";
919  $sql .= " AND (dbt.fk_soc IS NULL OR sc.fk_soc IS NOT NULL)"; // Contact not linked to a company or to a company of user
920  $sql .= " AND dbt.entity IN (".getEntity($sharedelement, 1).")";
921  } elseif (isModEnabled('multicompany')) {
922  // If multicompany and internal users with all permissions, check user is in correct entity
923  $sql = "SELECT COUNT(dbt.".$dbt_select.") as nb";
924  $sql .= " FROM ".MAIN_DB_PREFIX.$dbtablename." as dbt";
925  $sql .= " WHERE dbt.".$dbt_select." IN (".$db->sanitize($objectid, 1).")";
926  $sql .= " AND dbt.entity IN (".getEntity($sharedelement, 1).")";
927  }
928 
929  $checkonentitydone = 1;
930  }
931  if (in_array($feature, $checkproject) && $objectid > 0) {
932  if (isModEnabled('project') && empty($user->rights->projet->all->lire)) {
933  $projectid = $objectid;
934 
935  include_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
936  $projectstatic = new Project($db);
937  $tmps = $projectstatic->getProjectsAuthorizedForUser($user, 0, 1, 0);
938 
939  $tmparray = explode(',', $tmps);
940  if (!in_array($projectid, $tmparray)) {
941  return false;
942  }
943  } else {
944  $sql = "SELECT COUNT(dbt.".$dbt_select.") as nb";
945  $sql .= " FROM ".MAIN_DB_PREFIX.$dbtablename." as dbt";
946  $sql .= " WHERE dbt.".$dbt_select." IN (".$db->sanitize($objectid, 1).")";
947  $sql .= " AND dbt.entity IN (".getEntity($sharedelement, 1).")";
948  }
949 
950  $checkonentitydone = 1;
951  }
952  if (in_array($feature, $checktask) && $objectid > 0) {
953  if (isModEnabled('project') && empty($user->rights->projet->all->lire)) {
954  $task = new Task($db);
955  $task->fetch($objectid);
956  $projectid = $task->fk_project;
957 
958  include_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
959  $projectstatic = new Project($db);
960  $tmps = $projectstatic->getProjectsAuthorizedForUser($user, 0, 1, 0);
961 
962  $tmparray = explode(',', $tmps);
963  if (!in_array($projectid, $tmparray)) {
964  return false;
965  }
966  } else {
967  $sql = "SELECT COUNT(dbt.".$dbt_select.") as nb";
968  $sql .= " FROM ".MAIN_DB_PREFIX.$dbtablename." as dbt";
969  $sql .= " WHERE dbt.".$dbt_select." IN (".$db->sanitize($objectid, 1).")";
970  $sql .= " AND dbt.entity IN (".getEntity($sharedelement, 1).")";
971  }
972 
973  $checkonentitydone = 1;
974  }
975  if (!$checkonentitydone && !in_array($feature, $nocheck) && $objectid > 0) { // By default (case of $checkdefault), we check on object entity + link to third party on field $dbt_keyfield
976  // If external user: Check permission for external users
977  if ($user->socid > 0) {
978  if (empty($dbt_keyfield)) {
979  dol_print_error('', 'Param dbt_keyfield is required but not defined');
980  }
981  $sql = "SELECT COUNT(dbt.".$dbt_keyfield.") as nb";
982  $sql .= " FROM ".MAIN_DB_PREFIX.$dbtablename." as dbt";
983  $sql .= " WHERE dbt.rowid IN (".$db->sanitize($objectid, 1).")";
984  $sql .= " AND dbt.".$dbt_keyfield." = ".((int) $user->socid);
985  } elseif (isModEnabled("societe") && empty($user->rights->societe->client->voir)) {
986  // If internal user: Check permission for internal users that are restricted on their objects
987  if ($feature != 'ticket') {
988  if (empty($dbt_keyfield)) {
989  dol_print_error('', 'Param dbt_keyfield is required but not defined');
990  }
991  $sql = "SELECT COUNT(sc.fk_soc) as nb";
992  $sql .= " FROM ".MAIN_DB_PREFIX.$dbtablename." as dbt";
993  $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
994  $sql .= " WHERE dbt.".$dbt_select." IN (".$db->sanitize($objectid, 1).")";
995  $sql .= " AND dbt.entity IN (".getEntity($sharedelement, 1).")";
996  $sql .= " AND sc.fk_soc = dbt.".$dbt_keyfield;
997  $sql .= " AND sc.fk_user = ".((int) $user->id);
998  } else {
999  // On ticket, the thirdparty is not mandatory, so we need a special test to accept record with no thirdparties.
1000  $sql = "SELECT COUNT(dbt.".$dbt_select.") as nb";
1001  $sql .= " FROM ".MAIN_DB_PREFIX.$dbtablename." as dbt";
1002  $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON sc.fk_soc = dbt.".$dbt_keyfield." AND sc.fk_user = ".((int) $user->id);
1003  $sql .= " WHERE dbt.".$dbt_select." IN (".$db->sanitize($objectid, 1).")";
1004  $sql .= " AND dbt.entity IN (".getEntity($sharedelement, 1).")";
1005  $sql .= " AND (sc.fk_user = ".((int) $user->id)." OR sc.fk_user IS NULL)";
1006  }
1007  } elseif (isModEnabled('multicompany')) {
1008  // If multicompany and internal users with all permissions, check user is in correct entity
1009  $sql = "SELECT COUNT(dbt.".$dbt_select.") as nb";
1010  $sql .= " FROM ".MAIN_DB_PREFIX.$dbtablename." as dbt";
1011  $sql .= " WHERE dbt.".$dbt_select." IN (".$db->sanitize($objectid, 1).")";
1012  $sql .= " AND dbt.entity IN (".getEntity($sharedelement, 1).")";
1013  }
1014  }
1015  //print $sql;
1016 
1017  // For events, check on users assigned to event
1018  if ($feature === 'agenda' && $objectid > 0) {
1019  // Also check owner or attendee for users without allactions->read
1020  if ($objectid > 0 && empty($user->rights->agenda->allactions->read)) {
1021  require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php';
1022  $action = new ActionComm($db);
1023  $action->fetch($objectid);
1024  if ($action->authorid != $user->id && $action->userownerid != $user->id && !(array_key_exists($user->id, $action->userassigned))) {
1025  return false;
1026  }
1027  }
1028  }
1029 
1030  // For some object, we also have to check it is in the user hierarchy
1031  // Param $object must be the full object and not a simple id to have this test possible.
1032  if (in_array($feature, $checkhierarchy) && is_object($object) && $objectid > 0) {
1033  $childids = $user->getAllChildIds(1);
1034  $useridtocheck = 0;
1035  if ($feature == 'holiday') {
1036  $useridtocheck = $object->fk_user;
1037  if (!in_array($useridtocheck, $childids)) {
1038  return false;
1039  }
1040  $useridtocheck = $object->fk_validator;
1041  if (!in_array($useridtocheck, $childids)) {
1042  return false;
1043  }
1044  }
1045  if ($feature == 'expensereport') {
1046  $useridtocheck = $object->fk_user_author;
1047  if (!$user->rights->expensereport->readall) {
1048  if (!in_array($useridtocheck, $childids)) {
1049  return false;
1050  }
1051  }
1052  }
1053  }
1054 
1055  // For some object, we also have to check it is public or owned by user
1056  // Param $object must be the full object and not a simple id to have this test possible.
1057  if (in_array($feature, $checkuser) && is_object($object) && $objectid > 0) {
1058  $useridtocheck = $object->fk_user;
1059  if (!empty($useridtocheck) && $useridtocheck > 0 && $useridtocheck != $user->id && empty($user->admin)) {
1060  return false;
1061  }
1062  }
1063 
1064  if ($sql) {
1065  $resql = $db->query($sql);
1066  if ($resql) {
1067  $obj = $db->fetch_object($resql);
1068  if (!$obj || $obj->nb < count(explode(',', $objectid))) { // error if we found 0 or less record than nb of id provided
1069  return false;
1070  }
1071  } else {
1072  dol_syslog("Bad forged sql in checkUserAccessToObject", LOG_WARNING);
1073  return false;
1074  }
1075  }
1076  }
1077 
1078  return true;
1079 }
1080 
1081 
1093 function httponly_accessforbidden($message = 1, $http_response_code = 403, $stringalreadysanitized = 0)
1094 {
1095  top_httphead();
1096  http_response_code($http_response_code);
1097 
1098  if ($stringalreadysanitized) {
1099  print $message;
1100  } else {
1101  print htmlentities($message);
1102  }
1103 
1104  exit(1);
1105 }
1106 
1120 function accessforbidden($message = '', $printheader = 1, $printfooter = 1, $showonlymessage = 0, $params = null)
1121 {
1122  global $conf, $db, $user, $langs, $hookmanager;
1123 
1124  if (!is_object($langs)) {
1125  include_once DOL_DOCUMENT_ROOT.'/core/class/translate.class.php';
1126  $langs = new Translate('', $conf);
1127  $langs->setDefaultLang();
1128  }
1129 
1130  $langs->load("errors");
1131 
1132  if ($printheader) {
1133  if (function_exists("llxHeader")) {
1134  llxHeader('');
1135  } elseif (function_exists("llxHeaderVierge")) {
1136  llxHeaderVierge('');
1137  }
1138  }
1139  print '<div class="error">';
1140  if (empty($message)) {
1141  print $langs->trans("ErrorForbidden");
1142  } else {
1143  print $langs->trans($message);
1144  }
1145  print '</div>';
1146  print '<br>';
1147  if (empty($showonlymessage)) {
1148  global $action, $object;
1149  if (empty($hookmanager)) {
1150  $hookmanager = new HookManager($db);
1151  // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
1152  $hookmanager->initHooks(array('main'));
1153  }
1154  $parameters = array('message'=>$message, 'params'=>$params);
1155  $reshook = $hookmanager->executeHooks('getAccessForbiddenMessage', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
1156  print $hookmanager->resPrint;
1157  if (empty($reshook)) {
1158  $langs->loadLangs(array("errors"));
1159  if ($user->login) {
1160  print $langs->trans("CurrentLogin").': <span class="error">'.$user->login.'</span><br>';
1161  print $langs->trans("ErrorForbidden2", $langs->transnoentitiesnoconv("Home"), $langs->transnoentitiesnoconv("Users"));
1162  print $langs->trans("ErrorForbidden4");
1163  } else {
1164  print $langs->trans("ErrorForbidden3");
1165  }
1166  }
1167  }
1168  if ($printfooter && function_exists("llxFooter")) {
1169  llxFooter();
1170  }
1171 
1172  exit(0);
1173 }
1174 
1175 
1183 {
1184  global $conf;
1185 
1186  $max = $conf->global->MAIN_UPLOAD_DOC; // In Kb
1187  $maxphp = @ini_get('upload_max_filesize'); // In unknown
1188  if (preg_match('/k$/i', $maxphp)) {
1189  $maxphp = preg_replace('/k$/i', '', $maxphp);
1190  $maxphp = $maxphp * 1;
1191  }
1192  if (preg_match('/m$/i', $maxphp)) {
1193  $maxphp = preg_replace('/m$/i', '', $maxphp);
1194  $maxphp = $maxphp * 1024;
1195  }
1196  if (preg_match('/g$/i', $maxphp)) {
1197  $maxphp = preg_replace('/g$/i', '', $maxphp);
1198  $maxphp = $maxphp * 1024 * 1024;
1199  }
1200  if (preg_match('/t$/i', $maxphp)) {
1201  $maxphp = preg_replace('/t$/i', '', $maxphp);
1202  $maxphp = $maxphp * 1024 * 1024 * 1024;
1203  }
1204  $maxphp2 = @ini_get('post_max_size'); // In unknown
1205  if (preg_match('/k$/i', $maxphp2)) {
1206  $maxphp2 = preg_replace('/k$/i', '', $maxphp2);
1207  $maxphp2 = $maxphp2 * 1;
1208  }
1209  if (preg_match('/m$/i', $maxphp2)) {
1210  $maxphp2 = preg_replace('/m$/i', '', $maxphp2);
1211  $maxphp2 = $maxphp2 * 1024;
1212  }
1213  if (preg_match('/g$/i', $maxphp2)) {
1214  $maxphp2 = preg_replace('/g$/i', '', $maxphp2);
1215  $maxphp2 = $maxphp2 * 1024 * 1024;
1216  }
1217  if (preg_match('/t$/i', $maxphp2)) {
1218  $maxphp2 = preg_replace('/t$/i', '', $maxphp2);
1219  $maxphp2 = $maxphp2 * 1024 * 1024 * 1024;
1220  }
1221  // Now $max and $maxphp and $maxphp2 are in Kb
1222  $maxmin = $max;
1223  $maxphptoshow = $maxphptoshowparam = '';
1224  if ($maxphp > 0) {
1225  $maxmin = min($maxmin, $maxphp);
1226  $maxphptoshow = $maxphp;
1227  $maxphptoshowparam = 'upload_max_filesize';
1228  }
1229  if ($maxphp2 > 0) {
1230  $maxmin = min($maxmin, $maxphp2);
1231  if ($maxphp2 < $maxphp) {
1232  $maxphptoshow = $maxphp2;
1233  $maxphptoshowparam = 'post_max_size';
1234  }
1235  }
1236  //var_dump($maxphp.'-'.$maxphp2);
1237  //var_dump($maxmin);
1238 
1239  return array('max'=>$max, 'maxmin'=>$maxmin, 'maxphptoshow'=>$maxphptoshow, 'maxphptoshowparam'=>$maxphptoshowparam);
1240 }
httponly_accessforbidden
httponly_accessforbidden($message=1, $http_response_code=403, $stringalreadysanitized=0)
Show a message to say access is forbidden and stop program.
Definition: security.lib.php:1093
llxFooter
llxFooter()
Empty footer.
Definition: wrapper.php:70
Project
Class to manage projects.
Definition: project.class.php:35
ActionComm
Class to manage agenda events (actions)
Definition: actioncomm.class.php:38
dol_substr
dol_substr($string, $start, $length, $stringencoding='', $trunconbytes=0)
Make a substring.
Definition: functions.lib.php:3910
GETPOST
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
Definition: functions.lib.php:520
dol_print_error
dol_print_error($db='', $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
Definition: functions.lib.php:4993
dol_verifyHash
dol_verifyHash($chain, $hash, $type='0')
Compute a hash and compare it to the given one For backward compatibility reasons,...
Definition: security.lib.php:263
Translate
Class to manage translations.
Definition: translate.class.php:30
Task
Class to manage tasks.
Definition: task.class.php:37
top_httphead
if(!defined('NOREQUIREMENU')) if(!function_exists("llxHeader")) top_httphead($contenttype='text/html', $forcenocache=0)
Show HTTP header.
Definition: main.inc.php:1440
llxHeaderVierge
if(!defined('NOTOKENRENEWAL')) if(!defined('NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined('NOREQUIREAJAX')) if(!defined('NOLOGIN')) if(!defined('NOCSRFCHECK')) if(!defined('NOIPCHECK')) llxHeaderVierge()
Header function.
Definition: agendaexport.php:61
llxHeader
if(!defined('NOREQUIRESOC')) if(!defined('NOREQUIRETRAN')) if(!defined('NOTOKENRENEWAL')) if(!defined('NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined('NOREQUIREAJAX')) llxHeader()
Empty header.
Definition: wrapper.php:56
dolGetLdapPasswordHash
dolGetLdapPasswordHash($password, $type='md5')
Returns a specific ldap hash of a password.
Definition: security.lib.php:289
dol_hash
dol_hash($chain, $type='0')
Returns a hash (non reversible encryption) of a string.
Definition: security.lib.php:215
getMaxFileSizeArray
getMaxFileSizeArray()
Return the max allowed for file upload.
Definition: security.lib.php:1182
$resql
if(isModEnabled('facture') &&!empty($user->rights->facture->lire)) if((isModEnabled('fournisseur') &&empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && $user->hasRight("fournisseur", "facture", "lire"))||(isModEnabled('supplier_invoice') && $user->hasRight("supplier_invoice", "lire"))) if(isModEnabled('don') &&!empty($user->rights->don->lire)) if(isModEnabled('tax') &&!empty($user->rights->tax->charges->lire)) if(isModEnabled('facture') &&isModEnabled('commande') && $user->hasRight("commande", "lire") &&empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) $resql
Social contributions to pay.
Definition: index.php:745
dol_syslog
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
Definition: functions.lib.php:1628
dolEncrypt
dolEncrypt($chain, $key='', $ciphering='AES-256-CTR', $forceseed='')
Encode a string with a symetric encryption.
Definition: security.lib.php:120
getDolGlobalString
if(!function_exists('utf8_encode')) if(!function_exists('utf8_decode')) getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
Definition: functions.lib.php:82
dol_strlen
dol_strlen($string, $stringencoding='UTF-8')
Make a strlen call.
Definition: functions.lib.php:3887
restrictedArea
restrictedArea(User $user, $features, $object=0, $tableandshare='', $feature2='', $dbt_keyfield='fk_soc', $dbt_select='rowid', $isdraft=0, $mode=0)
Check permissions of a user to show a page and an object.
Definition: security.lib.php:346
isModEnabled
isModEnabled($module)
Is Dolibarr module enabled.
Definition: functions.lib.php:137
dol_encode
dol_encode($chain, $key='1')
Encode a string with base 64 algorithm + specific delta change.
Definition: security.lib.php:38
dolGetRandomBytes
dolGetRandomBytes($length)
Return a string of random bytes (hexa string) with length = $length fro cryptographic purposes.
Definition: security.lib.php:100
User
Class to manage Dolibarr users.
Definition: user.class.php:46
dolDecrypt
dolDecrypt($chain, $key='')
Decode a string with a symetric encryption.
Definition: security.lib.php:174
checkUserAccessToObject
checkUserAccessToObject($user, array $featuresarray, $object=0, $tableandshare='', $feature2='', $dbt_keyfield='', $dbt_select='rowid', $parenttableforentity='')
Check that access by a given user to an object is ok.
Definition: security.lib.php:784
accessforbidden
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program.
Definition: security.lib.php:1120
HookManager
Class to manage hooks.
Definition: hookmanager.class.php:30
dol_decode
dol_decode($chain, $key='1')
Decode a base 64 encoded + specific delta change.
Definition: security.lib.php:69