dolibarr  20.0.0-beta
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  * Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
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 3 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, see <https://www.gnu.org/licenses/>.
19  * or see https://www.gnu.org/
20  */
21 
39 function dol_encode($chain, $key = '1')
40 {
41  if (is_numeric($key) && $key == '1') { // rule 1 is offset of 17 for char
42  $output_tab = array();
43  $strlength = dol_strlen($chain);
44  for ($i = 0; $i < $strlength; $i++) {
45  $output_tab[$i] = chr(ord(substr($chain, $i, 1)) + 17);
46  }
47  $chain = implode("", $output_tab);
48  } elseif ($key) {
49  $result = '';
50  $strlength = dol_strlen($chain);
51  for ($i = 0; $i < $strlength; $i++) {
52  $keychar = substr($key, ($i % strlen($key)) - 1, 1);
53  $result .= chr(ord(substr($chain, $i, 1)) + (ord($keychar) - 65));
54  }
55  $chain = $result;
56  }
57 
58  return base64_encode($chain);
59 }
60 
70 function dol_decode($chain, $key = '1')
71 {
72  $chain = base64_decode($chain);
73 
74  if (is_numeric($key) && $key == '1') { // rule 1 is offset of 17 for char
75  $output_tab = array();
76  $strlength = dol_strlen($chain);
77  for ($i = 0; $i < $strlength; $i++) {
78  $output_tab[$i] = chr(ord(substr($chain, $i, 1)) - 17);
79  }
80 
81  $chain = implode("", $output_tab);
82  } elseif ($key) {
83  $result = '';
84  $strlength = dol_strlen($chain);
85  for ($i = 0; $i < $strlength; $i++) {
86  $keychar = substr($key, ($i % strlen($key)) - 1, 1);
87  $result .= chr(ord(substr($chain, $i, 1)) - (ord($keychar) - 65));
88  }
89  $chain = $result;
90  }
91 
92  return $chain;
93 }
94 
101 function dolGetRandomBytes($length)
102 {
103  if (function_exists('random_bytes')) { // Available with PHP 7 only.
104  return bin2hex(random_bytes((int) floor($length / 2))); // the bin2hex will double the number of bytes so we take length / 2
105  }
106 
107  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.
108 }
109 
123 function dolEncrypt($chain, $key = '', $ciphering = 'AES-256-CTR', $forceseed = '')
124 {
125  global $conf;
126  global $dolibarr_disable_dolcrypt_for_debug;
127 
128  if ($chain === '' || is_null($chain)) {
129  return '';
130  }
131 
132  $reg = array();
133  if (preg_match('/^dolcrypt:([^:]+):(.+)$/', $chain, $reg)) {
134  // The $chain is already a encrypted string
135  return $chain;
136  }
137 
138  if (empty($key)) {
139  $key = $conf->file->instance_unique_id;
140  }
141  if (empty($ciphering)) {
142  $ciphering = 'AES-256-CTR';
143  }
144 
145  $newchain = $chain;
146 
147  if (function_exists('openssl_encrypt') && empty($dolibarr_disable_dolcrypt_for_debug)) {
148  if (empty($key)) {
149  return $chain;
150  }
151 
152  $ivlen = 16;
153  if (function_exists('openssl_cipher_iv_length')) {
154  $ivlen = openssl_cipher_iv_length($ciphering);
155  }
156  if ($ivlen === false || $ivlen < 1 || $ivlen > 32) {
157  $ivlen = 16;
158  }
159  if (empty($forceseed)) {
160  $ivseed = dolGetRandomBytes($ivlen);
161  } else {
162  $ivseed = dol_substr(md5($forceseed), 0, $ivlen, 'ascii', 1);
163  }
164 
165  $newchain = openssl_encrypt($chain, $ciphering, $key, 0, $ivseed);
166  return 'dolcrypt:'.$ciphering.':'.$ivseed.':'.$newchain;
167  } else {
168  return $chain;
169  }
170 }
171 
182 function dolDecrypt($chain, $key = '')
183 {
184  global $conf;
185 
186  if ($chain === '' || is_null($chain)) {
187  return '';
188  }
189 
190  if (empty($key)) {
191  if (!empty($conf->file->dolcrypt_key)) {
192  // If dolcrypt_key is defined, we used it in priority
193  $key = $conf->file->dolcrypt_key;
194  } else {
195  // We fall back on the instance_unique_id
196  $key = $conf->file->instance_unique_id;
197  }
198  }
199 
200  //var_dump('key='.$key);
201  $reg = array();
202  if (preg_match('/^dolcrypt:([^:]+):(.+)$/', $chain, $reg)) {
203  $ciphering = $reg[1];
204  if (function_exists('openssl_decrypt')) {
205  if (empty($key)) {
206  dol_syslog("Error dolDecrypt decrypt key is empty", LOG_WARNING);
207  return $chain;
208  }
209  $tmpexplode = explode(':', $reg[2]);
210  if (!empty($tmpexplode[1]) && is_string($tmpexplode[0])) {
211  $newchain = openssl_decrypt($tmpexplode[1], $ciphering, $key, 0, $tmpexplode[0]);
212  } else {
213  $newchain = openssl_decrypt((string) $tmpexplode[0], $ciphering, $key, 0, '');
214  }
215  } else {
216  dol_syslog("Error dolDecrypt openssl_decrypt is not available", LOG_ERR);
217  return $chain;
218  }
219  return $newchain;
220  } else {
221  return $chain;
222  }
223 }
224 
237 function dol_hash($chain, $type = '0', $nosalt = 0)
238 {
239  // No need to add salt for password_hash
240  if (($type == '0' || $type == 'auto') && getDolGlobalString('MAIN_SECURITY_HASH_ALGO') && getDolGlobalString('MAIN_SECURITY_HASH_ALGO') == 'password_hash' && function_exists('password_hash')) {
241  return password_hash($chain, PASSWORD_DEFAULT);
242  }
243 
244  // Salt value
245  if (getDolGlobalString('MAIN_SECURITY_SALT') && $type != '4' && $type !== 'openldap' && empty($nosalt)) {
246  $chain = getDolGlobalString('MAIN_SECURITY_SALT') . $chain;
247  }
248 
249  if ($type == '1' || $type == 'sha1') {
250  return sha1($chain);
251  } elseif ($type == '2' || $type == 'sha1md5') {
252  return sha1(md5($chain));
253  } elseif ($type == '3' || $type == 'md5') { // For hashing with no need of security
254  return md5($chain);
255  } elseif ($type == '4' || $type == 'openldap') {
256  return dolGetLdapPasswordHash($chain, getDolGlobalString('LDAP_PASSWORD_HASH_TYPE', 'md5'));
257  } elseif ($type == '5' || $type == 'sha256') {
258  return hash('sha256', $chain);
259  } elseif ($type == '6' || $type == 'password_hash') {
260  return password_hash($chain, PASSWORD_DEFAULT);
261  } elseif (getDolGlobalString('MAIN_SECURITY_HASH_ALGO') == 'sha1') {
262  return sha1($chain);
263  } elseif (getDolGlobalString('MAIN_SECURITY_HASH_ALGO') == 'sha1md5') {
264  return sha1(md5($chain));
265  }
266 
267  // No particular encoding defined, use default
268  return md5($chain);
269 }
270 
283 function dol_verifyHash($chain, $hash, $type = '0')
284 {
285  if ($type == '0' && getDolGlobalString('MAIN_SECURITY_HASH_ALGO') && getDolGlobalString('MAIN_SECURITY_HASH_ALGO') == 'password_hash' && function_exists('password_verify')) {
286  if (! empty($hash[0]) && $hash[0] == '$') {
287  return password_verify($chain, $hash);
288  } elseif (dol_strlen($hash) == 32) {
289  return dol_verifyHash($chain, $hash, '3'); // md5
290  } elseif (dol_strlen($hash) == 40) {
291  return dol_verifyHash($chain, $hash, '2'); // sha1md5
292  }
293 
294  return false;
295  }
296 
297  return dol_hash($chain, $type) == $hash;
298 }
299 
307 function dolGetLdapPasswordHash($password, $type = 'md5')
308 {
309  if (empty($type)) {
310  $type = 'md5';
311  }
312 
313  $salt = substr(sha1((string) time()), 0, 8);
314 
315  if ($type === 'md5') {
316  return '{MD5}' . base64_encode(hash("md5", $password, true)); //For OpenLdap with md5 (based on an unencrypted password in base)
317  } elseif ($type === 'md5frommd5') {
318  return '{MD5}' . base64_encode(hex2bin($password)); // Create OpenLDAP MD5 password from Dolibarr MD5 password
319  } elseif ($type === 'smd5') {
320  return "{SMD5}" . base64_encode(hash("md5", $password . $salt, true) . $salt);
321  } elseif ($type === 'sha') {
322  return '{SHA}' . base64_encode(hash("sha1", $password, true));
323  } elseif ($type === 'ssha') {
324  return "{SSHA}" . base64_encode(hash("sha1", $password . $salt, true) . $salt);
325  } elseif ($type === 'sha256') {
326  return "{SHA256}" . base64_encode(hash("sha256", $password, true));
327  } elseif ($type === 'ssha256') {
328  return "{SSHA256}" . base64_encode(hash("sha256", $password . $salt, true) . $salt);
329  } elseif ($type === 'sha384') {
330  return "{SHA384}" . base64_encode(hash("sha384", $password, true));
331  } elseif ($type === 'ssha384') {
332  return "{SSHA384}" . base64_encode(hash("sha384", $password . $salt, true) . $salt);
333  } elseif ($type === 'sha512') {
334  return "{SHA512}" . base64_encode(hash("sha512", $password, true));
335  } elseif ($type === 'ssha512') {
336  return "{SSHA512}" . base64_encode(hash("sha512", $password . $salt, true) . $salt);
337  } elseif ($type === 'crypt') {
338  return '{CRYPT}' . crypt($password, $salt);
339  } elseif ($type === 'clear') {
340  return '{CLEAR}' . $password; // Just for test, plain text password is not secured !
341  }
342  return "";
343 }
344 
365 function restrictedArea(User $user, $features, $object = 0, $tableandshare = '', $feature2 = '', $dbt_keyfield = 'fk_soc', $dbt_select = 'rowid', $isdraft = 0, $mode = 0)
366 {
367  global $hookmanager;
368 
369  // Define $objectid
370  if (is_object($object)) {
371  $objectid = $object->id;
372  } else {
373  $objectid = $object; // $objectid can be X or 'X,Y,Z'
374  }
375  if ($objectid == "-1") {
376  $objectid = 0;
377  }
378  if ($objectid) {
379  $objectid = preg_replace('/[^0-9\.\,]/', '', (string) $objectid); // For the case value is coming from a non sanitized user input
380  }
381 
382  //dol_syslog("functions.lib:restrictedArea $feature, $objectid, $dbtablename, $feature2, $dbt_socfield, $dbt_select, $isdraft");
383  /*print "user_id=".$user->id.", features=".$features.", feature2=".$feature2.", objectid=".$objectid;
384  print ", dbtablename=".$tableandshare.", dbt_socfield=".$dbt_keyfield.", dbt_select=".$dbt_select;
385  print ", perm: user->hasRight(".$features.($feature2 ? ",".$feature2 : "").", lire) = ".($feature2 ? $user->hasRight($features, $feature2, 'lire') : $user->hasRight($features, 'lire'))."<br>";
386  */
387 
388  $parentfortableentity = '';
389 
390  // Fix syntax of $features param to support non standard module names.
391  $originalfeatures = $features;
392  if ($features == 'agenda') {
393  $tableandshare = 'actioncomm&societe';
394  $feature2 = 'myactions|allactions';
395  $dbt_select = 'id';
396  }
397  if ($features == 'bank') {
398  $features = 'banque';
399  }
400  if ($features == 'facturerec') {
401  $features = 'facture';
402  }
403  if ($features == 'supplier_invoicerec') {
404  $features = 'fournisseur';
405  $feature2 = 'facture';
406  }
407  if ($features == 'mo') {
408  $features = 'mrp';
409  }
410  if ($features == 'member') {
411  $features = 'adherent';
412  }
413  if ($features == 'subscription') {
414  $features = 'adherent';
415  $feature2 = 'cotisation';
416  }
417  if ($features == 'website' && is_object($object) && $object->element == 'websitepage') {
418  $parentfortableentity = 'fk_website@website';
419  }
420  if ($features == 'project') {
421  $features = 'projet';
422  }
423  if ($features == 'product') {
424  $features = 'produit';
425  }
426  if ($features == 'productbatch') {
427  $features = 'produit';
428  }
429  if ($features == 'tax') {
430  $feature2 = 'charges';
431  }
432  if ($features == 'workstation') {
433  $feature2 = 'workstation';
434  }
435  if ($features == 'fournisseur') { // When vendor invoice and purchase order are into module 'fournisseur'
436  $features = 'fournisseur';
437  if (is_object($object) && $object->element == 'invoice_supplier') {
438  $feature2 = 'facture';
439  } elseif (is_object($object) && $object->element == 'order_supplier') {
440  $feature2 = 'commande';
441  }
442  }
443  if ($features == 'payment_sc') {
444  $tableandshare = 'paiementcharge';
445  $parentfortableentity = 'fk_charge@chargesociales';
446  }
447 
448  //print $features.' - '.$tableandshare.' - '.$feature2.' - '.$dbt_select."\n";
449 
450  // Get more permissions checks from hooks
451  $parameters = array('features' => $features, 'originalfeatures' => $originalfeatures, 'objectid' => $objectid, 'dbt_select' => $dbt_select, 'idtype' => $dbt_select, 'isdraft' => $isdraft);
452  if (!empty($hookmanager)) {
453  $reshook = $hookmanager->executeHooks('restrictedArea', $parameters);
454 
455  if (isset($hookmanager->resArray['result'])) {
456  if ($hookmanager->resArray['result'] == 0) {
457  if ($mode) {
458  return 0;
459  } else {
460  accessforbidden(); // Module returns 0, so access forbidden
461  }
462  }
463  }
464  if ($reshook > 0) { // No other test done.
465  return 1;
466  }
467  }
468 
469  // Features/modules to check (to support the & and | operator)
470  $featuresarray = array($features);
471  if (preg_match('/&/', $features)) {
472  $featuresarray = explode("&", $features);
473  } elseif (preg_match('/\|/', $features)) {
474  $featuresarray = explode("|", $features);
475  }
476 
477  // More subfeatures to check
478  if (!empty($feature2)) {
479  $feature2 = explode("|", $feature2);
480  }
481 
482  $listofmodules = explode(',', getDolGlobalString('MAIN_MODULES_FOR_EXTERNAL'));
483 
484  // Check read permission from module
485  $readok = 1;
486  $nbko = 0;
487  foreach ($featuresarray as $feature) { // first we check nb of test ko
488  $featureforlistofmodule = $feature;
489  if ($featureforlistofmodule == 'produit') {
490  $featureforlistofmodule = 'product';
491  }
492  if ($featureforlistofmodule == 'supplier_proposal') {
493  $featureforlistofmodule = 'supplierproposal';
494  }
495  if (!empty($user->socid) && getDolGlobalString('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
496  $readok = 0;
497  $nbko++;
498  continue;
499  }
500 
501  if ($feature == 'societe' && (empty($feature2) || !in_array('contact', $feature2))) {
502  if (!$user->hasRight('societe', 'lire') && !$user->hasRight('fournisseur', 'lire')) {
503  $readok = 0;
504  $nbko++;
505  }
506  } elseif (($feature == 'societe' && (!empty($feature2) && in_array('contact', $feature2))) || $feature == 'contact') {
507  if (!$user->hasRight('societe', 'contact', 'lire')) {
508  $readok = 0;
509  $nbko++;
510  }
511  } elseif ($feature == 'produit|service') {
512  if (!$user->hasRight('produit', 'lire') && !$user->hasRight('service', 'lire')) {
513  $readok = 0;
514  $nbko++;
515  }
516  } elseif ($feature == 'prelevement') {
517  if (!$user->hasRight('prelevement', 'bons', 'lire')) {
518  $readok = 0;
519  $nbko++;
520  }
521  } elseif ($feature == 'cheque') {
522  if (!$user->hasRight('banque', 'cheque')) {
523  $readok = 0;
524  $nbko++;
525  }
526  } elseif ($feature == 'projet') {
527  if (!$user->hasRight('projet', 'lire') && !$user->hasRight('projet', 'all', 'lire')) {
528  $readok = 0;
529  $nbko++;
530  }
531  } elseif ($feature == 'payment') {
532  if (!$user->hasRight('facture', 'lire')) {
533  $readok = 0;
534  $nbko++;
535  }
536  } elseif ($feature == 'payment_supplier') {
537  if (!$user->hasRight('fournisseur', 'facture', 'lire')) {
538  $readok = 0;
539  $nbko++;
540  }
541  } elseif ($feature == 'payment_sc') {
542  if (!$user->hasRight('tax', 'charges', 'lire')) {
543  $readok = 0;
544  $nbko++;
545  }
546  } elseif (!empty($feature2)) { // This is for permissions on 2 levels (module->object->read)
547  $tmpreadok = 1;
548  foreach ($feature2 as $subfeature) {
549  if ($subfeature == 'user' && $user->id == $objectid) {
550  continue; // A user can always read its own card
551  }
552  if ($subfeature == 'fiscalyear' && $user->hasRight('accounting', 'fiscalyear', 'write')) {
553  // only one right for fiscalyear
554  $tmpreadok = 1;
555  continue;
556  }
557  if (!empty($subfeature) && !$user->hasRight($feature, $subfeature, 'lire') && !$user->hasRight($feature, $subfeature, 'read')) {
558  $tmpreadok = 0;
559  } elseif (empty($subfeature) && !$user->hasRight($feature, 'lire') && !$user->hasRight($feature, 'read')) {
560  $tmpreadok = 0;
561  } else {
562  $tmpreadok = 1;
563  break;
564  } // Break is to bypass second test if the first is ok
565  }
566  if (!$tmpreadok) { // We found a test on feature that is ko
567  $readok = 0; // All tests are ko (we manage here the and, the or will be managed later using $nbko).
568  $nbko++;
569  }
570  } elseif (!empty($feature) && ($feature != 'user' && $feature != 'usergroup')) { // This is permissions on 1 level (module->read)
571  if (!$user->hasRight($feature, 'lire')
572  && !$user->hasRight($feature, 'read')
573  && !$user->hasRight($feature, 'run')) {
574  $readok = 0;
575  $nbko++;
576  }
577  }
578  }
579 
580  // If a or and at least one ok
581  if (preg_match('/\|/', $features) && $nbko < count($featuresarray)) {
582  $readok = 1;
583  }
584 
585  if (!$readok) {
586  if ($mode) {
587  return 0;
588  } else {
589  accessforbidden();
590  }
591  }
592  //print "Read access is ok";
593 
594  // Check write permission from module (we need to know write permission to create but also to delete drafts record or to upload files)
595  $createok = 1;
596  $nbko = 0;
597  $wemustcheckpermissionforcreate = (GETPOST('sendit', 'alpha') || GETPOST('linkit', 'alpha') || in_array(GETPOST('action', 'aZ09'), array('create', 'update', 'set', 'upload', 'add_element_resource', 'confirm_deletebank', 'confirm_delete_linked_resource')) || GETPOST('roworder', 'alpha', 2));
598  $wemustcheckpermissionfordeletedraft = ((GETPOST("action", "aZ09") == 'confirm_delete' && GETPOST("confirm", "aZ09") == 'yes') || GETPOST("action", "aZ09") == 'delete');
599 
600  if ($wemustcheckpermissionforcreate || $wemustcheckpermissionfordeletedraft) {
601  foreach ($featuresarray as $feature) {
602  if ($feature == 'contact') {
603  if (!$user->hasRight('societe', 'contact', 'creer')) {
604  $createok = 0;
605  $nbko++;
606  }
607  } elseif ($feature == 'produit|service') {
608  if (!$user->hasRight('produit', 'creer') && !$user->hasRight('service', 'creer')) {
609  $createok = 0;
610  $nbko++;
611  }
612  } elseif ($feature == 'prelevement') {
613  if (!$user->hasRight('prelevement', 'bons', 'creer')) {
614  $createok = 0;
615  $nbko++;
616  }
617  } elseif ($feature == 'commande_fournisseur') {
618  if (!$user->hasRight('fournisseur', 'commande', 'creer') || !$user->hasRight('supplier_order', 'creer')) {
619  $createok = 0;
620  $nbko++;
621  }
622  } elseif ($feature == 'banque') {
623  if (!$user->hasRight('banque', 'modifier')) {
624  $createok = 0;
625  $nbko++;
626  }
627  } elseif ($feature == 'cheque') {
628  if (!$user->hasRight('banque', 'cheque')) {
629  $createok = 0;
630  $nbko++;
631  }
632  } elseif ($feature == 'import') {
633  if (!$user->hasRight('import', 'run')) {
634  $createok = 0;
635  $nbko++;
636  }
637  } elseif ($feature == 'ecm') {
638  if (!$user->hasRight('ecm', 'upload')) {
639  $createok = 0;
640  $nbko++;
641  }
642  } elseif ($feature == 'modulebuilder') {
643  if (!$user->hasRight('modulebuilder', 'run')) {
644  $createok = 0;
645  $nbko++;
646  }
647  } elseif (!empty($feature2)) { // This is for permissions on 2 levels (module->object->write)
648  foreach ($feature2 as $subfeature) {
649  if ($subfeature == 'user' && $user->id == $objectid && $user->hasRight('user', 'self', 'creer')) {
650  continue; // User can edit its own card
651  }
652  if ($subfeature == 'user' && $user->id == $objectid && $user->hasRight('user', 'self', 'password')) {
653  continue; // User can edit its own password
654  }
655  if ($subfeature == 'user' && $user->id != $objectid && $user->hasRight('user', 'user', 'password')) {
656  continue; // User can edit another user's password
657  }
658 
659  if (!$user->hasRight($feature, $subfeature, 'creer')
660  && !$user->hasRight($feature, $subfeature, 'write')
661  && !$user->hasRight($feature, $subfeature, 'create')) {
662  $createok = 0;
663  $nbko++;
664  } else {
665  $createok = 1;
666  // Break to bypass second test if the first is ok
667  break;
668  }
669  }
670  } elseif (!empty($feature)) { // This is for permissions on 1 levels (module->write)
671  //print '<br>feature='.$feature.' creer='.$user->rights->$feature->creer.' write='.$user->rights->$feature->write; exit;
672  if (!$user->hasRight($feature, 'creer')
673  && !$user->hasRight($feature, 'write')
674  && !$user->hasRight($feature, 'create')) {
675  $createok = 0;
676  $nbko++;
677  }
678  }
679  }
680 
681  // If a or and at least one ok
682  if (preg_match('/\|/', $features) && $nbko < count($featuresarray)) {
683  $createok = 1;
684  }
685 
686  if ($wemustcheckpermissionforcreate && !$createok) {
687  if ($mode) {
688  return 0;
689  } else {
690  accessforbidden();
691  }
692  }
693  //print "Write access is ok";
694  }
695 
696  // Check create user permission
697  $createuserok = 1;
698  if (GETPOST('action', 'aZ09') == 'confirm_create_user' && GETPOST("confirm", 'aZ09') == 'yes') {
699  if (!$user->hasRight('user', 'user', 'creer')) {
700  $createuserok = 0;
701  }
702 
703  if (!$createuserok) {
704  if ($mode) {
705  return 0;
706  } else {
707  accessforbidden();
708  }
709  }
710  //print "Create user access is ok";
711  }
712 
713  // Check delete permission from module
714  $deleteok = 1;
715  $nbko = 0;
716  if ((GETPOST("action", "aZ09") == 'confirm_delete' && GETPOST("confirm", "aZ09") == 'yes') || GETPOST("action", "aZ09") == 'delete') {
717  foreach ($featuresarray as $feature) {
718  if ($feature == 'bookmark') {
719  if (!$user->hasRight('bookmark', 'supprimer')) {
720  if ($user->id != $object->fk_user || !$user->hasRight('bookmark', 'creer')) {
721  $deleteok = 0;
722  }
723  }
724  } elseif ($feature == 'contact') {
725  if (!$user->hasRight('societe', 'contact', 'supprimer')) {
726  $deleteok = 0;
727  }
728  } elseif ($feature == 'produit|service') {
729  if (!$user->hasRight('produit', 'supprimer') && !$user->hasRight('service', 'supprimer')) {
730  $deleteok = 0;
731  }
732  } elseif ($feature == 'commande_fournisseur') {
733  if (!$user->hasRight('fournisseur', 'commande', 'supprimer')) {
734  $deleteok = 0;
735  }
736  } elseif ($feature == 'payment_supplier') { // Permission to delete a payment of an invoice is permission to edit an invoice.
737  if (!$user->hasRight('fournisseur', 'facture', 'creer')) {
738  $deleteok = 0;
739  }
740  } elseif ($feature == 'payment') {
741  if (!$user->hasRight('facture', 'paiement')) {
742  $deleteok = 0;
743  }
744  } elseif ($feature == 'payment_sc') {
745  if (!$user->hasRight('tax', 'charges', 'creer')) {
746  $deleteok = 0;
747  }
748  } elseif ($feature == 'banque') {
749  if (!$user->hasRight('banque', 'modifier')) {
750  $deleteok = 0;
751  }
752  } elseif ($feature == 'cheque') {
753  if (!$user->hasRight('banque', 'cheque')) {
754  $deleteok = 0;
755  }
756  } elseif ($feature == 'ecm') {
757  if (!$user->hasRight('ecm', 'upload')) {
758  $deleteok = 0;
759  }
760  } elseif ($feature == 'ftp') {
761  if (!$user->hasRight('ftp', 'write')) {
762  $deleteok = 0;
763  }
764  } elseif ($feature == 'salaries') {
765  if (!$user->hasRight('salaries', 'delete')) {
766  $deleteok = 0;
767  }
768  } elseif ($feature == 'adherent') {
769  if (!$user->hasRight('adherent', 'supprimer')) {
770  $deleteok = 0;
771  }
772  } elseif ($feature == 'paymentbybanktransfer') {
773  if (!$user->hasRight('paymentbybanktransfer', 'create')) { // There is no delete permission
774  $deleteok = 0;
775  }
776  } elseif ($feature == 'prelevement') {
777  if (!$user->hasRight('prelevement', 'bons', 'creer')) { // There is no delete permission
778  $deleteok = 0;
779  }
780  } elseif (!empty($feature2)) { // This is for permissions on 2 levels
781  foreach ($feature2 as $subfeature) {
782  if (!$user->hasRight($feature, $subfeature, 'supprimer') && !$user->hasRight($feature, $subfeature, 'delete')) {
783  $deleteok = 0;
784  } else {
785  $deleteok = 1;
786  break;
787  } // For bypass the second test if the first is ok
788  }
789  } elseif (!empty($feature)) { // This is used for permissions on 1 level
790  //print '<br>feature='.$feature.' creer='.$user->rights->$feature->supprimer.' write='.$user->rights->$feature->delete;
791  if (!$user->hasRight($feature, 'supprimer')
792  && !$user->hasRight($feature, 'delete')
793  && !$user->hasRight($feature, 'run')) {
794  $deleteok = 0;
795  }
796  }
797  }
798 
799  // If a or and at least one ok
800  if (preg_match('/\|/', $features) && $nbko < count($featuresarray)) {
801  $deleteok = 1;
802  }
803 
804  if (!$deleteok && !($isdraft && $createok)) {
805  if ($mode) {
806  return 0;
807  } else {
808  accessforbidden();
809  }
810  }
811  //print "Delete access is ok";
812  }
813 
814  // If we have a particular object to check permissions on, we check if $user has permission
815  // for this given object (link to company, is contact for project, ...)
816  if (!empty($objectid) && $objectid > 0) {
817  $ok = checkUserAccessToObject($user, $featuresarray, $object, $tableandshare, $feature2, $dbt_keyfield, $dbt_select, $parentfortableentity);
818  $params = array('objectid' => $objectid, 'features' => implode(',', $featuresarray), 'features2' => $feature2);
819  //print 'checkUserAccessToObject ok='.$ok;
820  if ($mode) {
821  return $ok ? 1 : 0;
822  } else {
823  if ($ok) {
824  return 1;
825  } else {
826  accessforbidden('', 1, 1, 0, $params);
827  }
828  }
829  }
830 
831  return 1;
832 }
833 
849 function checkUserAccessToObject($user, array $featuresarray, $object = 0, $tableandshare = '', $feature2 = '', $dbt_keyfield = '', $dbt_select = 'rowid', $parenttableforentity = '')
850 {
851  global $db, $conf;
852 
853  if (is_object($object)) {
854  $objectid = $object->id;
855  } else {
856  $objectid = $object; // $objectid can be X or 'X,Y,Z'
857  }
858  $objectid = preg_replace('/[^0-9\.\,]/', '', $objectid); // For the case value is coming from a non sanitized user input
859 
860  //dol_syslog("functions.lib:restrictedArea $feature, $objectid, $dbtablename, $feature2, $dbt_socfield, $dbt_select, $isdraft");
861  //print "user_id=".$user->id.", features=".join(',', $featuresarray).", objectid=".$objectid;
862  //print ", tableandshare=".$tableandshare.", dbt_socfield=".$dbt_keyfield.", dbt_select=".$dbt_select."<br>";
863 
864  // More parameters
865  $params = explode('&', $tableandshare);
866  $dbtablename = (!empty($params[0]) ? $params[0] : '');
867  $sharedelement = (!empty($params[1]) ? $params[1] : $dbtablename);
868 
869  foreach ($featuresarray as $feature) {
870  $sql = '';
871 
872  //var_dump($feature);exit;
873 
874  // For backward compatibility
875  if ($feature == 'societe' && !empty($feature2) && is_array($feature2) && in_array('contact', $feature2)) {
876  $feature = 'contact';
877  $feature2 = '';
878  }
879  if ($feature == 'member') {
880  $feature = 'adherent';
881  }
882  if ($feature == 'project') {
883  $feature = 'projet';
884  }
885  if ($feature == 'task') {
886  $feature = 'projet_task';
887  }
888  if ($feature == 'eventorganization') {
889  $feature = 'agenda';
890  $dbtablename = 'actioncomm';
891  }
892  if ($feature == 'payment_sc' && empty($parenttableforentity)) {
893  // If we check perm on payment page but $parenttableforentity not defined, we force value on parent table
894  $parenttableforentity = '';
895  $dbtablename = "chargesociales";
896  $feature = "chargesociales";
897  $objectid = $object->fk_charge;
898  }
899 
900  $checkonentitydone = 0;
901 
902  // Array to define rules of checks to do
903  $check = array('adherent', 'banque', 'bom', 'don', 'mrp', 'user', 'usergroup', 'payment', 'payment_supplier', 'payment_sc', 'product', 'produit', 'service', 'produit|service', 'categorie', 'resource', 'expensereport', 'holiday', 'salaries', 'website', 'recruitment', 'chargesociales', 'knowledgemanagement'); // Test on entity only (Objects with no link to company)
904  $checksoc = array('societe'); // Test for object Societe
905  $checkparentsoc = array('agenda', 'contact', 'contrat'); // Test on entity + link to third party on field $dbt_keyfield. Allowed if link is empty (Ex: contacts...).
906  $checkproject = array('projet', 'project'); // Test for project object
907  $checktask = array('projet_task'); // Test for task object
908  $checkhierarchy = array('expensereport', 'holiday'); // check permission among the hierarchy of user
909  $checkuser = array('bookmark'); // check permission among the fk_user (must be myself or null)
910  $nocheck = array('barcode', 'stock'); // No test
911 
912  //$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...).
913 
914  // If dbtablename not defined, we use same name for table than module name
915  if (empty($dbtablename)) {
916  $dbtablename = $feature;
917  $sharedelement = (!empty($params[1]) ? $params[1] : $dbtablename); // We change dbtablename, so we set sharedelement too.
918  }
919 
920  // To avoid an access forbidden with a numeric ref
921  if ($dbt_select != 'rowid' && $dbt_select != 'id') {
922  $objectid = "'".$objectid."'"; // Note: $objectid was already cast into int at begin of this method.
923  }
924  // Check permission for objectid on entity only
925  if (in_array($feature, $check) && $objectid > 0) { // For $objectid = 0, no check
926  $sql = "SELECT COUNT(dbt.".$dbt_select.") as nb";
927  $sql .= " FROM ".MAIN_DB_PREFIX.$dbtablename." as dbt";
928  if (($feature == 'user' || $feature == 'usergroup') && isModEnabled('multicompany')) { // Special for multicompany
929  if (getDolGlobalString('MULTICOMPANY_TRANSVERSE_MODE')) {
930  if ($conf->entity == 1 && $user->admin && !$user->entity) {
931  $sql .= " WHERE dbt.".$dbt_select." IN (".$db->sanitize($objectid, 1).")";
932  $sql .= " AND dbt.entity IS NOT NULL";
933  } else {
934  $sql .= ",".MAIN_DB_PREFIX."usergroup_user as ug";
935  $sql .= " WHERE dbt.".$dbt_select." IN (".$db->sanitize($objectid, 1).")";
936  $sql .= " AND ((ug.fk_user = dbt.rowid";
937  $sql .= " AND ug.entity IN (".getEntity('usergroup')."))";
938  $sql .= " OR dbt.entity = 0)"; // Show always superadmin
939  }
940  } else {
941  $sql .= " WHERE dbt.".$dbt_select." IN (".$db->sanitize($objectid, 1).")";
942  $sql .= " AND dbt.entity IN (".getEntity($sharedelement, 1).")";
943  }
944  } else {
945  $reg = array();
946  if ($parenttableforentity && preg_match('/(.*)@(.*)/', $parenttableforentity, $reg)) {
947  $sql .= ", ".MAIN_DB_PREFIX.$reg[2]." as dbtp";
948  $sql .= " WHERE dbt.".$reg[1]." = dbtp.rowid AND dbt.".$dbt_select." IN (".$db->sanitize($objectid, 1).")";
949  $sql .= " AND dbtp.entity IN (".getEntity($sharedelement, 1).")";
950  } else {
951  $sql .= " WHERE dbt.".$dbt_select." IN (".$db->sanitize($objectid, 1).")";
952  $sql .= " AND dbt.entity IN (".getEntity($sharedelement, 1).")";
953  }
954  }
955  $checkonentitydone = 1;
956  }
957  if (in_array($feature, $checksoc) && $objectid > 0) { // We check feature = checksoc. For $objectid = 0, no check
958  // If external user: Check permission for external users
959  if ($user->socid > 0) {
960  if ($user->socid != $objectid) {
961  return false;
962  }
963  } elseif (isModEnabled("societe") && ($user->hasRight('societe', 'lire') && !$user->hasRight('societe', 'client', 'voir'))) {
964  // If internal user: Check permission for internal users that are restricted on their objects
965  $sql = "SELECT COUNT(sc.fk_soc) as nb";
966  $sql .= " FROM (".MAIN_DB_PREFIX."societe_commerciaux as sc";
967  $sql .= ", ".MAIN_DB_PREFIX."societe as s)";
968  $sql .= " WHERE sc.fk_soc IN (".$db->sanitize($objectid, 1).")";
969  $sql .= " AND (sc.fk_user = ".((int) $user->id);
970  if (getDolGlobalInt('MAIN_SEE_SUBORDINATES')) {
971  $userschilds = $user->getAllChildIds();
972  $sql .= " OR sc.fk_user IN (".$db->sanitize(implode(',', $userschilds)).")";
973  }
974  $sql .= ")";
975  $sql .= " AND sc.fk_soc = s.rowid";
976  $sql .= " AND s.entity IN (".getEntity($sharedelement, 1).")";
977  } elseif (isModEnabled('multicompany')) {
978  // If multicompany and internal users with all permissions, check user is in correct entity
979  $sql = "SELECT COUNT(s.rowid) as nb";
980  $sql .= " FROM ".MAIN_DB_PREFIX."societe as s";
981  $sql .= " WHERE s.rowid IN (".$db->sanitize($objectid, 1).")";
982  $sql .= " AND s.entity IN (".getEntity($sharedelement, 1).")";
983  }
984 
985  $checkonentitydone = 1;
986  }
987  if (in_array($feature, $checkparentsoc) && $objectid > 0) { // Test on entity + link to thirdparty. Allowed if link is empty (Ex: contacts...).
988  // If external user: Check permission for external users
989  if ($user->socid > 0) {
990  $sql = "SELECT COUNT(dbt.".$dbt_select.") as nb";
991  $sql .= " FROM ".MAIN_DB_PREFIX.$dbtablename." as dbt";
992  $sql .= " WHERE dbt.".$dbt_select." IN (".$db->sanitize($objectid, 1).")";
993  $sql .= " AND dbt.fk_soc = ".((int) $user->socid);
994  } elseif (isModEnabled("societe") && ($user->hasRight('societe', 'lire') && !$user->hasRight('societe', 'client', 'voir'))) {
995  // If internal user: Check permission for internal users that are restricted on their objects
996  $sql = "SELECT COUNT(dbt.".$dbt_select.") as nb";
997  $sql .= " FROM ".MAIN_DB_PREFIX.$dbtablename." as dbt";
998  $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON dbt.fk_soc = sc.fk_soc AND sc.fk_user = ".((int) $user->id);
999  $sql .= " WHERE dbt.".$dbt_select." IN (".$db->sanitize($objectid, 1).")";
1000  $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
1001  $sql .= " AND dbt.entity IN (".getEntity($sharedelement, 1).")";
1002  } elseif (isModEnabled('multicompany')) {
1003  // If multicompany and internal users with all permissions, check user is in correct entity
1004  $sql = "SELECT COUNT(dbt.".$dbt_select.") as nb";
1005  $sql .= " FROM ".MAIN_DB_PREFIX.$dbtablename." as dbt";
1006  $sql .= " WHERE dbt.".$dbt_select." IN (".$db->sanitize($objectid, 1).")";
1007  $sql .= " AND dbt.entity IN (".getEntity($sharedelement, 1).")";
1008  }
1009 
1010  $checkonentitydone = 1;
1011  }
1012  if (in_array($feature, $checkproject) && $objectid > 0) {
1013  if (isModEnabled('project') && !$user->hasRight('projet', 'all', 'lire')) {
1014  $projectid = $objectid;
1015 
1016  include_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
1017  $projectstatic = new Project($db);
1018  $tmps = $projectstatic->getProjectsAuthorizedForUser($user, 0, 1, 0);
1019 
1020  $tmparray = explode(',', $tmps);
1021  if (!in_array($projectid, $tmparray)) {
1022  return false;
1023  }
1024  } else {
1025  $sql = "SELECT COUNT(dbt.".$dbt_select.") as nb";
1026  $sql .= " FROM ".MAIN_DB_PREFIX.$dbtablename." as dbt";
1027  $sql .= " WHERE dbt.".$dbt_select." IN (".$db->sanitize($objectid, 1).")";
1028  $sql .= " AND dbt.entity IN (".getEntity($sharedelement, 1).")";
1029  }
1030  $checkonentitydone = 1;
1031  }
1032  if (in_array($feature, $checktask) && $objectid > 0) {
1033  if (isModEnabled('project') && !$user->hasRight('projet', 'all', 'lire')) {
1034  $task = new Task($db);
1035  $task->fetch($objectid);
1036  $projectid = $task->fk_project;
1037 
1038  include_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
1039  $projectstatic = new Project($db);
1040  $tmps = $projectstatic->getProjectsAuthorizedForUser($user, 0, 1, 0);
1041 
1042  $tmparray = explode(',', $tmps);
1043  if (!in_array($projectid, $tmparray)) {
1044  return false;
1045  }
1046  } else {
1047  $sql = "SELECT COUNT(dbt.".$dbt_select.") as nb";
1048  $sql .= " FROM ".MAIN_DB_PREFIX.$dbtablename." as dbt";
1049  $sql .= " WHERE dbt.".$dbt_select." IN (".$db->sanitize($objectid, 1).")";
1050  $sql .= " AND dbt.entity IN (".getEntity($sharedelement, 1).")";
1051  }
1052 
1053  $checkonentitydone = 1;
1054  }
1055  //var_dump($sql);
1056 
1057  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
1058  // If external user: Check permission for external users
1059  if ($user->socid > 0) {
1060  if (empty($dbt_keyfield)) {
1061  dol_print_error(null, 'Param dbt_keyfield is required but not defined');
1062  }
1063  $sql = "SELECT COUNT(dbt.".$dbt_keyfield.") as nb";
1064  $sql .= " FROM ".MAIN_DB_PREFIX.$dbtablename." as dbt";
1065  $sql .= " WHERE dbt.rowid IN (".$db->sanitize($objectid, 1).")";
1066  $sql .= " AND dbt.".$dbt_keyfield." = ".((int) $user->socid);
1067  } elseif (isModEnabled("societe") && !$user->hasRight('societe', 'client', 'voir')) {
1068  // If internal user without permission to see all thirdparties: Check permission for internal users that are restricted on their objects
1069  if ($feature != 'ticket') {
1070  if (empty($dbt_keyfield)) {
1071  dol_print_error(null, 'Param dbt_keyfield is required but not defined');
1072  }
1073  $sql = "SELECT COUNT(sc.fk_soc) as nb";
1074  $sql .= " FROM ".MAIN_DB_PREFIX.$dbtablename." as dbt";
1075  $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
1076  $sql .= " WHERE dbt.".$dbt_select." IN (".$db->sanitize($objectid, 1).")";
1077  $sql .= " AND dbt.entity IN (".getEntity($sharedelement, 1).")";
1078  $sql .= " AND sc.fk_soc = dbt.".$dbt_keyfield;
1079  $sql .= " AND (sc.fk_user = ".((int) $user->id);
1080  if (getDolGlobalInt('MAIN_SEE_SUBORDINATES')) {
1081  $userschilds = $user->getAllChildIds();
1082  foreach ($userschilds as $key => $value) {
1083  $sql .= ' OR sc.fk_user = '.((int) $value);
1084  }
1085  }
1086  $sql .= ')';
1087  } else {
1088  // On ticket, the thirdparty is not mandatory, so we need a special test to accept record with no thirdparties.
1089  $sql = "SELECT COUNT(dbt.".$dbt_select.") as nb";
1090  $sql .= " FROM ".MAIN_DB_PREFIX.$dbtablename." as dbt";
1091  $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON sc.fk_soc = dbt.".$dbt_keyfield." AND sc.fk_user = ".((int) $user->id);
1092  $sql .= " WHERE dbt.".$dbt_select." IN (".$db->sanitize($objectid, 1).")";
1093  $sql .= " AND dbt.entity IN (".getEntity($sharedelement, 1).")";
1094  $sql .= " AND (sc.fk_user = ".((int) $user->id)." OR sc.fk_user IS NULL)";
1095  }
1096  } elseif (isModEnabled('multicompany')) {
1097  // If multicompany, and user is an internal user with all permissions, check that object is in correct entity
1098  $sql = "SELECT COUNT(dbt.".$dbt_select.") as nb";
1099  $sql .= " FROM ".MAIN_DB_PREFIX.$dbtablename." as dbt";
1100  $sql .= " WHERE dbt.".$dbt_select." IN (".$db->sanitize($objectid, 1).")";
1101  $sql .= " AND dbt.entity IN (".getEntity($sharedelement, 1).")";
1102  }
1103  }
1104 
1105  // For events, check on users assigned to event
1106  if ($feature === 'agenda' && $objectid > 0) {
1107  // Also check owner or attendee for users without allactions->read
1108  if ($objectid > 0 && !$user->hasRight('agenda', 'allactions', 'read')) {
1109  require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php';
1110  $action = new ActionComm($db);
1111  $action->fetch($objectid);
1112  if ($action->authorid != $user->id && $action->userownerid != $user->id && !(array_key_exists($user->id, $action->userassigned))) {
1113  return false;
1114  }
1115  }
1116  }
1117 
1118  // For some object, we also have to check it is in the user hierarchy
1119  // Param $object must be the full object and not a simple id to have this test possible.
1120  if (in_array($feature, $checkhierarchy) && is_object($object) && $objectid > 0) {
1121  $childids = $user->getAllChildIds(1);
1122  $useridtocheck = 0;
1123  if ($feature == 'holiday') {
1124  $useridtocheck = $object->fk_user;
1125  if (!$user->hasRight('holiday', 'readall') && !in_array($useridtocheck, $childids) && !in_array($object->fk_validator, $childids)) {
1126  return false;
1127  }
1128  }
1129  if ($feature == 'expensereport') {
1130  $useridtocheck = $object->fk_user_author;
1131  if (!$user->hasRight('expensereport', 'readall')) {
1132  if (!in_array($useridtocheck, $childids)) {
1133  return false;
1134  }
1135  }
1136  }
1137  }
1138 
1139  // For some object, we also have to check it is public or owned by user
1140  // Param $object must be the full object and not a simple id to have this test possible.
1141  if (in_array($feature, $checkuser) && is_object($object) && $objectid > 0) {
1142  $useridtocheck = $object->fk_user;
1143  if (!empty($useridtocheck) && $useridtocheck > 0 && $useridtocheck != $user->id && empty($user->admin)) {
1144  return false;
1145  }
1146  }
1147 
1148  if ($sql) {
1149  $resql = $db->query($sql);
1150  if ($resql) {
1151  $obj = $db->fetch_object($resql);
1152  if (!$obj || $obj->nb < count(explode(',', $objectid))) { // error if we found 0 or less record than nb of id provided
1153  return false;
1154  }
1155  } else {
1156  dol_syslog("Bad forged sql in checkUserAccessToObject", LOG_WARNING);
1157  return false;
1158  }
1159  }
1160  }
1161 
1162  return true;
1163 }
1164 
1165 
1177 function httponly_accessforbidden($message = '1', $http_response_code = 403, $stringalreadysanitized = 0)
1178 {
1179  top_httphead();
1180  http_response_code($http_response_code);
1181 
1182  if ($stringalreadysanitized) {
1183  print $message;
1184  } else {
1185  print htmlentities($message);
1186  }
1187 
1188  exit(1);
1189 }
1190 
1204 function accessforbidden($message = '', $printheader = 1, $printfooter = 1, $showonlymessage = 0, $params = null)
1205 {
1206  global $conf, $db, $user, $langs, $hookmanager;
1207  global $action, $object;
1208 
1209  if (!is_object($langs)) {
1210  include_once DOL_DOCUMENT_ROOT.'/core/class/translate.class.php';
1211  $langs = new Translate('', $conf);
1212  $langs->setDefaultLang();
1213  }
1214 
1215  $langs->loadLangs(array("main", "errors"));
1216 
1217  if ($printheader && !defined('NOHEADERNOFOOTER')) {
1218  if (function_exists("llxHeader")) {
1219  llxHeader('');
1220  } elseif (function_exists("llxHeaderVierge")) {
1221  llxHeaderVierge('');
1222  }
1223  print '<div style="padding: 20px">';
1224  }
1225  print '<div class="error">';
1226  if (empty($message)) {
1227  print $langs->trans("ErrorForbidden");
1228  } else {
1229  print $langs->trans($message);
1230  }
1231  print '</div>';
1232  print '<br>';
1233  if (empty($showonlymessage)) {
1234  if (empty($hookmanager)) {
1235  include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php';
1236  $hookmanager = new HookManager($db);
1237  // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
1238  $hookmanager->initHooks(array('main'));
1239  }
1240 
1241  $parameters = array('message' => $message, 'params' => $params);
1242  $reshook = $hookmanager->executeHooks('getAccessForbiddenMessage', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
1243  print $hookmanager->resPrint;
1244  if (empty($reshook)) {
1245  $langs->loadLangs(array("errors"));
1246  if ($user->login) {
1247  print $langs->trans("CurrentLogin").': <span class="error">'.$user->login.'</span><br>';
1248  print $langs->trans("ErrorForbidden2", $langs->transnoentitiesnoconv("Home"), $langs->transnoentitiesnoconv("Users"));
1249  print $langs->trans("ErrorForbidden4");
1250  } else {
1251  print $langs->trans("ErrorForbidden3");
1252  }
1253  }
1254  }
1255  if ($printfooter && !defined('NOHEADERNOFOOTER') && function_exists("llxFooter")) {
1256  print '</div>';
1257  llxFooter();
1258  }
1259 
1260  exit(0);
1261 }
1262 
1263 
1271 {
1272  $max = getDolGlobalString('MAIN_UPLOAD_DOC'); // In Kb
1273 
1274  $maxphp = @ini_get('upload_max_filesize'); // In unknown
1275  if (preg_match('/k$/i', $maxphp)) {
1276  $maxphp = preg_replace('/k$/i', '', $maxphp);
1277  $maxphp = $maxphp * 1;
1278  }
1279  if (preg_match('/m$/i', $maxphp)) {
1280  $maxphp = preg_replace('/m$/i', '', $maxphp);
1281  $maxphp = $maxphp * 1024;
1282  }
1283  if (preg_match('/g$/i', $maxphp)) {
1284  $maxphp = preg_replace('/g$/i', '', $maxphp);
1285  $maxphp = $maxphp * 1024 * 1024;
1286  }
1287  if (preg_match('/t$/i', $maxphp)) {
1288  $maxphp = preg_replace('/t$/i', '', $maxphp);
1289  $maxphp = $maxphp * 1024 * 1024 * 1024;
1290  }
1291  $maxphp2 = @ini_get('post_max_size'); // In unknown
1292  if (preg_match('/k$/i', $maxphp2)) {
1293  $maxphp2 = preg_replace('/k$/i', '', $maxphp2);
1294  $maxphp2 = $maxphp2 * 1;
1295  }
1296  if (preg_match('/m$/i', $maxphp2)) {
1297  $maxphp2 = preg_replace('/m$/i', '', $maxphp2);
1298  $maxphp2 = $maxphp2 * 1024;
1299  }
1300  if (preg_match('/g$/i', $maxphp2)) {
1301  $maxphp2 = preg_replace('/g$/i', '', $maxphp2);
1302  $maxphp2 = $maxphp2 * 1024 * 1024;
1303  }
1304  if (preg_match('/t$/i', $maxphp2)) {
1305  $maxphp2 = preg_replace('/t$/i', '', $maxphp2);
1306  $maxphp2 = $maxphp2 * 1024 * 1024 * 1024;
1307  }
1308  // Now $max and $maxphp and $maxphp2 are in Kb
1309  $maxmin = $max;
1310  $maxphptoshow = $maxphptoshowparam = '';
1311  if ($maxphp > 0) {
1312  $maxmin = min($maxmin, $maxphp);
1313  $maxphptoshow = $maxphp;
1314  $maxphptoshowparam = 'upload_max_filesize';
1315  }
1316  if ($maxphp2 > 0) {
1317  $maxmin = min($maxmin, $maxphp2);
1318  if ($maxphp2 < $maxphp) {
1319  $maxphptoshow = $maxphp2;
1320  $maxphptoshowparam = 'post_max_size';
1321  }
1322  }
1323  //var_dump($maxphp.'-'.$maxphp2);
1324  //var_dump($maxmin);
1325 
1326  return array('max' => $max, 'maxmin' => $maxmin, 'maxphptoshow' => $maxphptoshow, 'maxphptoshowparam' => $maxphptoshowparam);
1327 }
if($user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition: card.php:58
if(!defined('NOTOKENRENEWAL')) if(!defined('NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined('NOREQUIREAJAX')) if(!defined('NOLOGIN')) if(!defined('NOCSRFCHECK')) if(!defined('NOIPCHECK')) llxHeaderVierge()
Header function.
if(!defined('NOREQUIRESOC')) if(!defined('NOREQUIRETRAN')) if(!defined('NOTOKENRENEWAL')) if(!defined('NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined('NOREQUIREAJAX')) llxHeader()
Empty header.
Definition: wrapper.php:55
llxFooter()
Empty footer.
Definition: wrapper.php:69
Class to manage agenda events (actions)
Class to manage hooks.
Class to manage projects.
Class to manage tasks.
Definition: task.class.php:41
Class to manage translations.
Class to manage Dolibarr users.
Definition: user.class.php:50
if(isModEnabled('invoice') && $user->hasRight('facture', 'lire')) if((isModEnabled('fournisseur') &&!getDolGlobalString('MAIN_USE_NEW_SUPPLIERMOD') && $user->hasRight("fournisseur", "facture", "lire"))||(isModEnabled('supplier_invoice') && $user->hasRight("supplier_invoice", "lire"))) if(isModEnabled('don') && $user->hasRight('don', 'lire')) if(isModEnabled('tax') && $user->hasRight('tax', 'charges', 'lire')) if(isModEnabled('invoice') &&isModEnabled('order') && $user->hasRight("commande", "lire") &&!getDolGlobalString('WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER')) $sql
Social contributions to pay.
Definition: index.php:745
dol_strlen($string, $stringencoding='UTF-8')
Make a strlen call.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
dol_substr($string, $start, $length=null, $stringencoding='', $trunconbytes=0)
Make a substring.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
isModEnabled($module)
Is Dolibarr module enabled.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
if(!defined('NOREQUIREMENU')) if(!empty(GETPOST('seteventmessages', 'alpha'))) if(!function_exists("llxHeader")) top_httphead($contenttype='text/html', $forcenocache=0)
Show HTTP header.
Definition: main.inc.php:1648
dolEncrypt($chain, $key='', $ciphering='AES-256-CTR', $forceseed='')
Encode a string with a symmetric encryption.
dolGetRandomBytes($length)
Return a string of random bytes (hexa string) with length = $length for cryptographic purposes.
httponly_accessforbidden($message='1', $http_response_code=403, $stringalreadysanitized=0)
Show a message to say access is forbidden and stop program.
dol_encode($chain, $key='1')
Encode a string with base 64 algorithm + specific delta change.
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.
dol_verifyHash($chain, $hash, $type='0')
Compute a hash and compare it to the given one For backward compatibility reasons,...
getMaxFileSizeArray()
Return the max allowed for file upload.
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.
dol_decode($chain, $key='1')
Decode a base 64 encoded + specific delta change.
dolGetLdapPasswordHash($password, $type='md5')
Returns a specific ldap hash of a password.
dolDecrypt($chain, $key='')
Decode a string with a symmetric encryption.
dol_hash($chain, $type='0', $nosalt=0)
Returns a hash (non reversible encryption) of a string.
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program.