dolibarr  18.0.6
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 
122 function dolEncrypt($chain, $key = '', $ciphering = 'AES-256-CTR', $forceseed = '')
123 {
124  global $conf;
125  global $dolibarr_disable_dolcrypt_for_debug;
126 
127  if ($chain === '' || is_null($chain)) {
128  return '';
129  }
130 
131  $reg = array();
132  if (preg_match('/^dolcrypt:([^:]+):(.+)$/', $chain, $reg)) {
133  // The $chain is already a crypted string
134  return $chain;
135  }
136 
137  if (empty($key)) {
138  $key = $conf->file->instance_unique_id;
139  }
140  if (empty($ciphering)) {
141  $ciphering = 'AES-256-CTR';
142  }
143 
144  $newchain = $chain;
145 
146  if (function_exists('openssl_encrypt') && empty($dolibarr_disable_dolcrypt_for_debug)) {
147  if (empty($key)) {
148  return $chain;
149  }
150 
151  $ivlen = 16;
152  if (function_exists('openssl_cipher_iv_length')) {
153  $ivlen = openssl_cipher_iv_length($ciphering);
154  }
155  if ($ivlen === false || $ivlen < 1 || $ivlen > 32) {
156  $ivlen = 16;
157  }
158  if (empty($forceseed)) {
159  $ivseed = dolGetRandomBytes($ivlen);
160  } else {
161  $ivseed = dol_substr(md5($forceseed), 0, $ivlen, 'ascii', 1);
162  }
163 
164  $newchain = openssl_encrypt($chain, $ciphering, $key, 0, $ivseed);
165  return 'dolcrypt:'.$ciphering.':'.$ivseed.':'.$newchain;
166  } else {
167  return $chain;
168  }
169 }
170 
181 function dolDecrypt($chain, $key = '')
182 {
183  global $conf;
184 
185  if ($chain === '' || is_null($chain)) {
186  return '';
187  }
188 
189  if (empty($key)) {
190  if (!empty($conf->file->dolcrypt_key)) {
191  // If dolcrypt_key is defined, we used it in priority
192  $key = $conf->file->dolcrypt_key;
193  } else {
194  // We fall back on the instance_unique_id
195  $key = $conf->file->instance_unique_id;
196  }
197  }
198 
199  //var_dump('key='.$key);
200  $reg = array();
201  if (preg_match('/^dolcrypt:([^:]+):(.+)$/', $chain, $reg)) {
202  $ciphering = $reg[1];
203  if (function_exists('openssl_decrypt')) {
204  if (empty($key)) {
205  dol_syslog("Error dolDecrypt decrypt key is empty", LOG_WARNING);
206  return $chain;
207  }
208  $tmpexplode = explode(':', $reg[2]);
209  if (!empty($tmpexplode[1]) && is_string($tmpexplode[0])) {
210  $newchain = openssl_decrypt($tmpexplode[1], $ciphering, $key, 0, $tmpexplode[0]);
211  } else {
212  $newchain = openssl_decrypt($tmpexplode[0], $ciphering, $key, 0, null);
213  }
214  } else {
215  dol_syslog("Error dolDecrypt openssl_decrypt is not available", LOG_ERR);
216  return $chain;
217  }
218  return $newchain;
219  } else {
220  return $chain;
221  }
222 }
223 
234 function dol_hash($chain, $type = '0')
235 {
236  global $conf;
237 
238  // No need to add salt for password_hash
239  if (($type == '0' || $type == 'auto') && !empty($conf->global->MAIN_SECURITY_HASH_ALGO) && $conf->global->MAIN_SECURITY_HASH_ALGO == 'password_hash' && function_exists('password_hash')) {
240  return password_hash($chain, PASSWORD_DEFAULT);
241  }
242 
243  // Salt value
244  if (!empty($conf->global->MAIN_SECURITY_SALT) && $type != '4' && $type !== 'openldap') {
245  $chain = $conf->global->MAIN_SECURITY_SALT.$chain;
246  }
247 
248  if ($type == '1' || $type == 'sha1') {
249  return sha1($chain);
250  } elseif ($type == '2' || $type == 'sha1md5') {
251  return sha1(md5($chain));
252  } elseif ($type == '3' || $type == 'md5') {
253  return md5($chain);
254  } elseif ($type == '4' || $type == 'openldap') {
255  return dolGetLdapPasswordHash($chain, getDolGlobalString('LDAP_PASSWORD_HASH_TYPE', 'md5'));
256  } elseif ($type == '5' || $type == 'sha256') {
257  return hash('sha256', $chain);
258  } elseif ($type == '6' || $type == 'password_hash') {
259  return password_hash($chain, PASSWORD_DEFAULT);
260  } elseif (!empty($conf->global->MAIN_SECURITY_HASH_ALGO) && $conf->global->MAIN_SECURITY_HASH_ALGO == 'sha1') {
261  return sha1($chain);
262  } elseif (!empty($conf->global->MAIN_SECURITY_HASH_ALGO) && $conf->global->MAIN_SECURITY_HASH_ALGO == 'sha1md5') {
263  return sha1(md5($chain));
264  }
265 
266  // No particular encoding defined, use default
267  return md5($chain);
268 }
269 
282 function dol_verifyHash($chain, $hash, $type = '0')
283 {
284  global $conf;
285 
286  if ($type == '0' && !empty($conf->global->MAIN_SECURITY_HASH_ALGO) && $conf->global->MAIN_SECURITY_HASH_ALGO == 'password_hash' && function_exists('password_verify')) {
287  if (! empty($hash[0]) && $hash[0] == '$') {
288  return password_verify($chain, $hash);
289  } elseif (dol_strlen($hash) == 32) {
290  return dol_verifyHash($chain, $hash, '3'); // md5
291  } elseif (dol_strlen($hash) == 40) {
292  return dol_verifyHash($chain, $hash, '2'); // sha1md5
293  }
294 
295  return false;
296  }
297 
298  return dol_hash($chain, $type) == $hash;
299 }
300 
308 function dolGetLdapPasswordHash($password, $type = 'md5')
309 {
310  if (empty($type)) {
311  $type = 'md5';
312  }
313 
314  $salt = substr(sha1(time()), 0, 8);
315 
316  if ($type === 'md5') {
317  return '{MD5}' . base64_encode(hash("md5", $password, true)); //For OpenLdap with md5 (based on an unencrypted password in base)
318  } elseif ($type === 'md5frommd5') {
319  return '{MD5}' . base64_encode(hex2bin($password)); // Create OpenLDAP MD5 password from Dolibarr MD5 password
320  } elseif ($type === 'smd5') {
321  return "{SMD5}" . base64_encode(hash("md5", $password . $salt, true) . $salt);
322  } elseif ($type === 'sha') {
323  return '{SHA}' . base64_encode(hash("sha1", $password, true));
324  } elseif ($type === 'ssha') {
325  return "{SSHA}" . base64_encode(hash("sha1", $password . $salt, true) . $salt);
326  } elseif ($type === 'sha256') {
327  return "{SHA256}" . base64_encode(hash("sha256", $password, true));
328  } elseif ($type === 'ssha256') {
329  return "{SSHA256}" . base64_encode(hash("sha256", $password . $salt, true) . $salt);
330  } elseif ($type === 'sha384') {
331  return "{SHA384}" . base64_encode(hash("sha384", $password, true));
332  } elseif ($type === 'ssha384') {
333  return "{SSHA384}" . base64_encode(hash("sha384", $password . $salt, true) . $salt);
334  } elseif ($type === 'sha512') {
335  return "{SHA512}" . base64_encode(hash("sha512", $password, true));
336  } elseif ($type === 'ssha512') {
337  return "{SSHA512}" . base64_encode(hash("sha512", $password . $salt, true) . $salt);
338  } elseif ($type === 'crypt') {
339  return '{CRYPT}' . crypt($password, $salt);
340  } elseif ($type === 'clear') {
341  return '{CLEAR}' . $password; // Just for test, plain text password is not secured !
342  }
343  return "";
344 }
345 
366 function restrictedArea(User $user, $features, $object = 0, $tableandshare = '', $feature2 = '', $dbt_keyfield = 'fk_soc', $dbt_select = 'rowid', $isdraft = 0, $mode = 0)
367 {
368  global $db, $conf;
369  global $hookmanager;
370 
371  // Define $objectid
372  if (is_object($object)) {
373  $objectid = $object->id;
374  } else {
375  $objectid = $object; // $objectid can be X or 'X,Y,Z'
376  }
377  if ($objectid == "-1") {
378  $objectid = 0;
379  }
380  if ($objectid) {
381  $objectid = preg_replace('/[^0-9\.\,]/', '', $objectid); // For the case value is coming from a non sanitized user input
382  }
383 
384  //dol_syslog("functions.lib:restrictedArea $feature, $objectid, $dbtablename, $feature2, $dbt_socfield, $dbt_select, $isdraft");
385  /*print "user_id=".$user->id.", features=".$features.", feature2=".$feature2.", objectid=".$objectid;
386  print ", dbtablename=".$tableandshare.", dbt_socfield=".$dbt_keyfield.", dbt_select=".$dbt_select;
387  print ", perm: user->right->".$features.($feature2 ? "->".$feature2 : "")."=".($user->hasRight($features, $feature2, 'lire'))."<br>";
388  */
389 
390  $parentfortableentity = '';
391 
392  // Fix syntax of $features param
393  $originalfeatures = $features;
394  if ($features == 'agenda') {
395  $tableandshare = 'actioncomm&societe';
396  $feature2 = 'myactions|allactions';
397  $dbt_select = 'id';
398  }
399  if ($features == 'bank') {
400  $features = 'banque';
401  }
402  if ($features == 'facturerec') {
403  $features = 'facture';
404  }
405  if ($features == 'supplier_invoicerec') {
406  $features = 'fournisseur';
407  $feature2 = 'facture';
408  }
409  if ($features == 'mo') {
410  $features = 'mrp';
411  }
412  if ($features == 'member') {
413  $features = 'adherent';
414  }
415  if ($features == 'subscription') {
416  $features = 'adherent';
417  $feature2 = 'cotisation';
418  }
419  if ($features == 'website' && is_object($object) && $object->element == 'websitepage') {
420  $parentfortableentity = 'fk_website@website';
421  }
422  if ($features == 'project') {
423  $features = 'projet';
424  }
425  if ($features == 'product') {
426  $features = 'produit';
427  }
428  if ($features == 'productbatch') {
429  $features = 'produit';
430  }
431  if ($features == 'tax') {
432  $feature2 = 'charges';
433  }
434  if ($features == 'workstation') {
435  $feature2 = 'workstation';
436  }
437  if ($features == 'fournisseur') { // When vendor invoice and purchase order are into module 'fournisseur'
438  $features = 'fournisseur';
439  if (is_object($object) && $object->element == 'invoice_supplier') {
440  $feature2 = 'facture';
441  } elseif (is_object($object) && $object->element == 'order_supplier') {
442  $feature2 = 'commande';
443  }
444  }
445  if ($features == 'payment_sc') {
446  $tableandshare = 'paiementcharge';
447  $parentfortableentity = 'fk_charge@chargesociales';
448  }
449 
450  //print $features.' - '.$tableandshare.' - '.$feature2.' - '.$dbt_select."\n";
451 
452  // Get more permissions checks from hooks
453  $parameters = array('features'=>$features, 'originalfeatures'=>$originalfeatures, 'objectid'=>$objectid, 'dbt_select'=>$dbt_select, 'idtype'=>$dbt_select, 'isdraft'=>$isdraft);
454  $reshook = $hookmanager->executeHooks('restrictedArea', $parameters);
455 
456  if (isset($hookmanager->resArray['result'])) {
457  if ($hookmanager->resArray['result'] == 0) {
458  if ($mode) {
459  return 0;
460  } else {
461  accessforbidden(); // Module returns 0, so access forbidden
462  }
463  }
464  }
465  if ($reshook > 0) { // No other test done.
466  return 1;
467  }
468 
469  // Features/modules to check
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(',', $conf->global->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) && !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
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 (empty($user->rights->societe->contact->lire)) {
508  $readok = 0;
509  $nbko++;
510  }
511  } elseif ($feature == 'produit|service') {
512  if (empty($user->rights->produit->lire) && empty($user->rights->service->lire)) {
513  $readok = 0;
514  $nbko++;
515  }
516  } elseif ($feature == 'prelevement') {
517  if (empty($user->rights->prelevement->bons->lire)) {
518  $readok = 0;
519  $nbko++;
520  }
521  } elseif ($feature == 'cheque') {
522  if (empty($user->rights->banque->cheque)) {
523  $readok = 0;
524  $nbko++;
525  }
526  } elseif ($feature == 'projet') {
527  if (empty($user->rights->projet->lire) && empty($user->rights->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 (empty($user->rights->fournisseur->facture->lire)) {
538  $readok = 0;
539  $nbko++;
540  }
541  } elseif ($feature == 'payment_sc') {
542  if (empty($user->rights->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) && empty($user->rights->$feature->$subfeature->lire) && empty($user->rights->$feature->$subfeature->read)) {
558  $tmpreadok = 0;
559  } elseif (empty($subfeature) && empty($user->rights->$feature->lire) && empty($user->rights->$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 (empty($user->rights->$feature->lire)
572  && empty($user->rights->$feature->read)
573  && empty($user->rights->$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 (empty($user->rights->societe->contact->creer)) {
604  $createok = 0;
605  $nbko++;
606  }
607  } elseif ($feature == 'produit|service') {
608  if (empty($user->rights->produit->creer) && empty($user->rights->service->creer)) {
609  $createok = 0;
610  $nbko++;
611  }
612  } elseif ($feature == 'prelevement') {
613  if (!$user->rights->prelevement->bons->creer) {
614  $createok = 0;
615  $nbko++;
616  }
617  } elseif ($feature == 'commande_fournisseur') {
618  if (empty($user->rights->fournisseur->commande->creer) || empty($user->rights->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 (empty($user->rights->banque->cheque)) {
629  $createok = 0;
630  $nbko++;
631  }
632  } elseif ($feature == 'import') {
633  if (empty($user->rights->import->run)) {
634  $createok = 0;
635  $nbko++;
636  }
637  } elseif ($feature == 'ecm') {
638  if (!$user->rights->ecm->upload) {
639  $createok = 0;
640  $nbko++;
641  }
642  } elseif (!empty($feature2)) { // This is for permissions on 2 levels (module->object->write)
643  foreach ($feature2 as $subfeature) {
644  if ($subfeature == 'user' && $user->id == $objectid && $user->hasRight('user', 'self', 'creer')) {
645  continue; // User can edit its own card
646  }
647  if ($subfeature == 'user' && $user->id == $objectid && $user->hasRight('user', 'self', 'password')) {
648  continue; // User can edit its own password
649  }
650  if ($subfeature == 'user' && $user->id != $objectid && $user->hasRight('user', 'user', 'password')) {
651  continue; // User can edit another user's password
652  }
653 
654  if (empty($user->rights->$feature->$subfeature->creer)
655  && empty($user->rights->$feature->$subfeature->write)
656  && empty($user->rights->$feature->$subfeature->create)) {
657  $createok = 0;
658  $nbko++;
659  } else {
660  $createok = 1;
661  // Break to bypass second test if the first is ok
662  break;
663  }
664  }
665  } elseif (!empty($feature)) { // This is for permissions on 1 levels (module->write)
666  //print '<br>feature='.$feature.' creer='.$user->rights->$feature->creer.' write='.$user->rights->$feature->write; exit;
667  if (empty($user->rights->$feature->creer)
668  && empty($user->rights->$feature->write)
669  && empty($user->rights->$feature->create)) {
670  $createok = 0;
671  $nbko++;
672  }
673  }
674  }
675 
676  // If a or and at least one ok
677  if (preg_match('/\|/', $features) && $nbko < count($featuresarray)) {
678  $createok = 1;
679  }
680 
681  if ($wemustcheckpermissionforcreate && !$createok) {
682  if ($mode) {
683  return 0;
684  } else {
685  accessforbidden();
686  }
687  }
688  //print "Write access is ok";
689  }
690 
691  // Check create user permission
692  $createuserok = 1;
693  if (GETPOST('action', 'aZ09') == 'confirm_create_user' && GETPOST("confirm", 'aZ09') == 'yes') {
694  if (!$user->hasRight('user', 'user', 'creer')) {
695  $createuserok = 0;
696  }
697 
698  if (!$createuserok) {
699  if ($mode) {
700  return 0;
701  } else {
702  accessforbidden();
703  }
704  }
705  //print "Create user access is ok";
706  }
707 
708  // Check delete permission from module
709  $deleteok = 1;
710  $nbko = 0;
711  if ((GETPOST("action", "aZ09") == 'confirm_delete' && GETPOST("confirm", "aZ09") == 'yes') || GETPOST("action", "aZ09") == 'delete') {
712  foreach ($featuresarray as $feature) {
713  if ($feature == 'bookmark') {
714  if (!$user->rights->bookmark->supprimer) {
715  if ($user->id != $object->fk_user || empty($user->rights->bookmark->creer)) {
716  $deleteok = 0;
717  }
718  }
719  } elseif ($feature == 'contact') {
720  if (!$user->rights->societe->contact->supprimer) {
721  $deleteok = 0;
722  }
723  } elseif ($feature == 'produit|service') {
724  if (!$user->hasRight('produit', 'supprimer') && !$user->hasRight('service', 'supprimer')) {
725  $deleteok = 0;
726  }
727  } elseif ($feature == 'commande_fournisseur') {
728  if (!$user->rights->fournisseur->commande->supprimer) {
729  $deleteok = 0;
730  }
731  } elseif ($feature == 'payment_supplier') { // Permission to delete a payment of an invoice is permission to edit an invoice.
732  if (!$user->rights->fournisseur->facture->creer) {
733  $deleteok = 0;
734  }
735  } elseif ($feature == 'payment') {
736  if (!$user->rights->facture->paiement) {
737  $deleteok = 0;
738  }
739  } elseif ($feature == 'payment_sc') {
740  if (!$user->rights->tax->charges->creer) {
741  $deleteok = 0;
742  }
743  } elseif ($feature == 'banque') {
744  if (!$user->hasRight('banque', 'modifier')) {
745  $deleteok = 0;
746  }
747  } elseif ($feature == 'cheque') {
748  if (empty($user->rights->banque->cheque)) {
749  $deleteok = 0;
750  }
751  } elseif ($feature == 'ecm') {
752  if (!$user->rights->ecm->upload) {
753  $deleteok = 0;
754  }
755  } elseif ($feature == 'ftp') {
756  if (!$user->rights->ftp->write) {
757  $deleteok = 0;
758  }
759  } elseif ($feature == 'salaries') {
760  if (!$user->rights->salaries->delete) {
761  $deleteok = 0;
762  }
763  } elseif ($feature == 'adherent') {
764  if (empty($user->rights->adherent->supprimer)) {
765  $deleteok = 0;
766  }
767  } elseif ($feature == 'paymentbybanktransfer') {
768  if (empty($user->rights->paymentbybanktransfer->create)) { // There is no delete permission
769  $deleteok = 0;
770  }
771  } elseif ($feature == 'prelevement') {
772  if (empty($user->rights->prelevement->bons->creer)) { // There is no delete permission
773  $deleteok = 0;
774  }
775  } elseif (!empty($feature2)) { // This is for permissions on 2 levels
776  foreach ($feature2 as $subfeature) {
777  if (empty($user->rights->$feature->$subfeature->supprimer) && empty($user->rights->$feature->$subfeature->delete)) {
778  $deleteok = 0;
779  } else {
780  $deleteok = 1;
781  break;
782  } // For bypass the second test if the first is ok
783  }
784  } elseif (!empty($feature)) { // This is used for permissions on 1 level
785  //print '<br>feature='.$feature.' creer='.$user->rights->$feature->supprimer.' write='.$user->rights->$feature->delete;
786  if (empty($user->rights->$feature->supprimer)
787  && empty($user->rights->$feature->delete)
788  && empty($user->rights->$feature->run)) {
789  $deleteok = 0;
790  }
791  }
792  }
793 
794  // If a or and at least one ok
795  if (preg_match('/\|/', $features) && $nbko < count($featuresarray)) {
796  $deleteok = 1;
797  }
798 
799  if (!$deleteok && !($isdraft && $createok)) {
800  if ($mode) {
801  return 0;
802  } else {
803  accessforbidden();
804  }
805  }
806  //print "Delete access is ok";
807  }
808 
809  // If we have a particular object to check permissions on, we check if $user has permission
810  // for this given object (link to company, is contact for project, ...)
811  if (!empty($objectid) && $objectid > 0) {
812  $ok = checkUserAccessToObject($user, $featuresarray, $object, $tableandshare, $feature2, $dbt_keyfield, $dbt_select, $parentfortableentity);
813  $params = array('objectid' => $objectid, 'features' => join(',', $featuresarray), 'features2' => $feature2);
814  //print 'checkUserAccessToObject ok='.$ok;
815  if ($mode) {
816  return $ok ? 1 : 0;
817  } else {
818  if ($ok) {
819  return 1;
820  } else {
821  accessforbidden('', 1, 1, 0, $params);
822  }
823  }
824  }
825 
826  return 1;
827 }
828 
844 function checkUserAccessToObject($user, array $featuresarray, $object = 0, $tableandshare = '', $feature2 = '', $dbt_keyfield = '', $dbt_select = 'rowid', $parenttableforentity = '')
845 {
846  global $db, $conf;
847 
848  if (is_object($object)) {
849  $objectid = $object->id;
850  } else {
851  $objectid = $object; // $objectid can be X or 'X,Y,Z'
852  }
853  $objectid = preg_replace('/[^0-9\.\,]/', '', $objectid); // For the case value is coming from a non sanitized user input
854 
855  //dol_syslog("functions.lib:restrictedArea $feature, $objectid, $dbtablename, $feature2, $dbt_socfield, $dbt_select, $isdraft");
856  //print "user_id=".$user->id.", features=".join(',', $featuresarray).", objectid=".$objectid;
857  //print ", tableandshare=".$tableandshare.", dbt_socfield=".$dbt_keyfield.", dbt_select=".$dbt_select."<br>";
858 
859  // More parameters
860  $params = explode('&', $tableandshare);
861  $dbtablename = (!empty($params[0]) ? $params[0] : '');
862  $sharedelement = (!empty($params[1]) ? $params[1] : $dbtablename);
863 
864  foreach ($featuresarray as $feature) {
865  $sql = '';
866 
867  //var_dump($feature);exit;
868 
869  // For backward compatibility
870  if ($feature == 'societe' && !empty($feature2) && is_array($feature2) && in_array('contact', $feature2)) {
871  $feature = 'contact';
872  $feature2 = '';
873  }
874  if ($feature == 'member') {
875  $feature = 'adherent';
876  }
877  if ($feature == 'project') {
878  $feature = 'projet';
879  }
880  if ($feature == 'task') {
881  $feature = 'projet_task';
882  }
883  if ($feature == 'eventorganization') {
884  $feature = 'agenda';
885  $dbtablename = 'actioncomm';
886  }
887  if ($feature == 'payment_sc' && empty($parenttableforentity)) {
888  // If we check perm on payment page but $parenttableforentity not defined, we force value on parent table
889  $parenttableforentity = '';
890  $dbtablename = "chargesociales";
891  $feature = "chargesociales";
892  $objectid = $object->fk_charge;
893  }
894 
895  $checkonentitydone = 0;
896 
897  // Array to define rules of checks to do
898  $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)
899  $checksoc = array('societe'); // Test for object Societe
900  $checkparentsoc = array('agenda', 'contact', 'contrat'); // Test on entity + link to third party on field $dbt_keyfield. Allowed if link is empty (Ex: contacts...).
901  $checkproject = array('projet', 'project'); // Test for project object
902  $checktask = array('projet_task'); // Test for task object
903  $checkhierarchy = array('expensereport', 'holiday'); // check permission among the hierarchy of user
904  $checkuser = array('bookmark'); // check permission among the fk_user (must be myself or null)
905  $nocheck = array('barcode', 'stock'); // No test
906 
907  //$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...).
908 
909  // If dbtablename not defined, we use same name for table than module name
910  if (empty($dbtablename)) {
911  $dbtablename = $feature;
912  $sharedelement = (!empty($params[1]) ? $params[1] : $dbtablename); // We change dbtablename, so we set sharedelement too.
913  }
914 
915  // To avoid an access forbidden with a numeric ref
916  if ($dbt_select != 'rowid' && $dbt_select != 'id') {
917  $objectid = "'".$objectid."'"; // Note: $objectid was already cast into int at begin of this method.
918  }
919  // Check permission for objectid on entity only
920  if (in_array($feature, $check) && $objectid > 0) { // For $objectid = 0, no check
921  $sql = "SELECT COUNT(dbt.".$dbt_select.") as nb";
922  $sql .= " FROM ".MAIN_DB_PREFIX.$dbtablename." as dbt";
923  if (($feature == 'user' || $feature == 'usergroup') && isModEnabled('multicompany')) { // Special for multicompany
924  if (!empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) {
925  if ($conf->entity == 1 && $user->admin && !$user->entity) {
926  $sql .= " WHERE dbt.".$dbt_select." IN (".$db->sanitize($objectid, 1).")";
927  $sql .= " AND dbt.entity IS NOT NULL";
928  } else {
929  $sql .= ",".MAIN_DB_PREFIX."usergroup_user as ug";
930  $sql .= " WHERE dbt.".$dbt_select." IN (".$db->sanitize($objectid, 1).")";
931  $sql .= " AND ((ug.fk_user = dbt.rowid";
932  $sql .= " AND ug.entity IN (".getEntity('usergroup')."))";
933  $sql .= " OR dbt.entity = 0)"; // Show always superadmin
934  }
935  } else {
936  $sql .= " WHERE dbt.".$dbt_select." IN (".$db->sanitize($objectid, 1).")";
937  $sql .= " AND dbt.entity IN (".getEntity($sharedelement, 1).")";
938  }
939  } else {
940  $reg = array();
941  if ($parenttableforentity && preg_match('/(.*)@(.*)/', $parenttableforentity, $reg)) {
942  $sql .= ", ".MAIN_DB_PREFIX.$reg[2]." as dbtp";
943  $sql .= " WHERE dbt.".$reg[1]." = dbtp.rowid AND dbt.".$dbt_select." IN (".$db->sanitize($objectid, 1).")";
944  $sql .= " AND dbtp.entity IN (".getEntity($sharedelement, 1).")";
945  } else {
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, $checksoc) && $objectid > 0) { // We check feature = checksoc. For $objectid = 0, no check
953  // If external user: Check permission for external users
954  if ($user->socid > 0) {
955  if ($user->socid != $objectid) {
956  return false;
957  }
958  } elseif (isModEnabled("societe") && ($user->hasRight('societe', 'lire') && empty($user->rights->societe->client->voir))) {
959  // If internal user: Check permission for internal users that are restricted on their objects
960  $sql = "SELECT COUNT(sc.fk_soc) as nb";
961  $sql .= " FROM (".MAIN_DB_PREFIX."societe_commerciaux as sc";
962  $sql .= ", ".MAIN_DB_PREFIX."societe as s)";
963  $sql .= " WHERE sc.fk_soc IN (".$db->sanitize($objectid, 1).")";
964  $sql .= " AND sc.fk_user = ".((int) $user->id);
965  $sql .= " AND sc.fk_soc = s.rowid";
966  $sql .= " AND s.entity IN (".getEntity($sharedelement, 1).")";
967  } elseif (isModEnabled('multicompany')) {
968  // If multicompany and internal users with all permissions, check user is in correct entity
969  $sql = "SELECT COUNT(s.rowid) as nb";
970  $sql .= " FROM ".MAIN_DB_PREFIX."societe as s";
971  $sql .= " WHERE s.rowid IN (".$db->sanitize($objectid, 1).")";
972  $sql .= " AND s.entity IN (".getEntity($sharedelement, 1).")";
973  }
974 
975  $checkonentitydone = 1;
976  }
977  if (in_array($feature, $checkparentsoc) && $objectid > 0) { // Test on entity + link to thirdparty. Allowed if link is empty (Ex: contacts...).
978  // If external user: Check permission for external users
979  if ($user->socid > 0) {
980  $sql = "SELECT COUNT(dbt.".$dbt_select.") as nb";
981  $sql .= " FROM ".MAIN_DB_PREFIX.$dbtablename." as dbt";
982  $sql .= " WHERE dbt.".$dbt_select." IN (".$db->sanitize($objectid, 1).")";
983  $sql .= " AND dbt.fk_soc = ".((int) $user->socid);
984  } elseif (isModEnabled("societe") && ($user->hasRight('societe', 'lire') && empty($user->rights->societe->client->voir))) {
985  // If internal user: Check permission for internal users that are restricted on their objects
986  $sql = "SELECT COUNT(dbt.".$dbt_select.") as nb";
987  $sql .= " FROM ".MAIN_DB_PREFIX.$dbtablename." as dbt";
988  $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON dbt.fk_soc = sc.fk_soc AND sc.fk_user = ".((int) $user->id);
989  $sql .= " WHERE dbt.".$dbt_select." IN (".$db->sanitize($objectid, 1).")";
990  $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
991  $sql .= " AND dbt.entity IN (".getEntity($sharedelement, 1).")";
992  } elseif (isModEnabled('multicompany')) {
993  // If multicompany and internal users with all permissions, check user is in correct entity
994  $sql = "SELECT COUNT(dbt.".$dbt_select.") as nb";
995  $sql .= " FROM ".MAIN_DB_PREFIX.$dbtablename." as dbt";
996  $sql .= " WHERE dbt.".$dbt_select." IN (".$db->sanitize($objectid, 1).")";
997  $sql .= " AND dbt.entity IN (".getEntity($sharedelement, 1).")";
998  }
999 
1000  $checkonentitydone = 1;
1001  }
1002  if (in_array($feature, $checkproject) && $objectid > 0) {
1003  if (isModEnabled('project') && empty($user->rights->projet->all->lire)) {
1004  $projectid = $objectid;
1005 
1006  include_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
1007  $projectstatic = new Project($db);
1008  $tmps = $projectstatic->getProjectsAuthorizedForUser($user, 0, 1, 0);
1009 
1010  $tmparray = explode(',', $tmps);
1011  if (!in_array($projectid, $tmparray)) {
1012  return false;
1013  }
1014  } else {
1015  $sql = "SELECT COUNT(dbt.".$dbt_select.") as nb";
1016  $sql .= " FROM ".MAIN_DB_PREFIX.$dbtablename." as dbt";
1017  $sql .= " WHERE dbt.".$dbt_select." IN (".$db->sanitize($objectid, 1).")";
1018  $sql .= " AND dbt.entity IN (".getEntity($sharedelement, 1).")";
1019  }
1020  $checkonentitydone = 1;
1021  }
1022  if (in_array($feature, $checktask) && $objectid > 0) {
1023  if (isModEnabled('project') && empty($user->rights->projet->all->lire)) {
1024  $task = new Task($db);
1025  $task->fetch($objectid);
1026  $projectid = $task->fk_project;
1027 
1028  include_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
1029  $projectstatic = new Project($db);
1030  $tmps = $projectstatic->getProjectsAuthorizedForUser($user, 0, 1, 0);
1031 
1032  $tmparray = explode(',', $tmps);
1033  if (!in_array($projectid, $tmparray)) {
1034  return false;
1035  }
1036  } else {
1037  $sql = "SELECT COUNT(dbt.".$dbt_select.") as nb";
1038  $sql .= " FROM ".MAIN_DB_PREFIX.$dbtablename." as dbt";
1039  $sql .= " WHERE dbt.".$dbt_select." IN (".$db->sanitize($objectid, 1).")";
1040  $sql .= " AND dbt.entity IN (".getEntity($sharedelement, 1).")";
1041  }
1042 
1043  $checkonentitydone = 1;
1044  }
1045  //var_dump($sql);
1046 
1047  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
1048  // If external user: Check permission for external users
1049  if ($user->socid > 0) {
1050  if (empty($dbt_keyfield)) {
1051  dol_print_error('', 'Param dbt_keyfield is required but not defined');
1052  }
1053  $sql = "SELECT COUNT(dbt.".$dbt_keyfield.") as nb";
1054  $sql .= " FROM ".MAIN_DB_PREFIX.$dbtablename." as dbt";
1055  $sql .= " WHERE dbt.rowid IN (".$db->sanitize($objectid, 1).")";
1056  $sql .= " AND dbt.".$dbt_keyfield." = ".((int) $user->socid);
1057  } elseif (isModEnabled("societe") && empty($user->rights->societe->client->voir)) {
1058  // If internal user without permission to see all thirdparties: Check permission for internal users that are restricted on their objects
1059  if ($feature != 'ticket') {
1060  if (empty($dbt_keyfield)) {
1061  dol_print_error('', 'Param dbt_keyfield is required but not defined');
1062  }
1063  $sql = "SELECT COUNT(sc.fk_soc) as nb";
1064  $sql .= " FROM ".MAIN_DB_PREFIX.$dbtablename." as dbt";
1065  $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
1066  $sql .= " WHERE dbt.".$dbt_select." IN (".$db->sanitize($objectid, 1).")";
1067  $sql .= " AND dbt.entity IN (".getEntity($sharedelement, 1).")";
1068  $sql .= " AND sc.fk_soc = dbt.".$dbt_keyfield;
1069  $sql .= " AND sc.fk_user = ".((int) $user->id);
1070  } else {
1071  // On ticket, the thirdparty is not mandatory, so we need a special test to accept record with no thirdparties.
1072  $sql = "SELECT COUNT(dbt.".$dbt_select.") as nb";
1073  $sql .= " FROM ".MAIN_DB_PREFIX.$dbtablename." as dbt";
1074  $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON sc.fk_soc = dbt.".$dbt_keyfield." AND sc.fk_user = ".((int) $user->id);
1075  $sql .= " WHERE dbt.".$dbt_select." IN (".$db->sanitize($objectid, 1).")";
1076  $sql .= " AND dbt.entity IN (".getEntity($sharedelement, 1).")";
1077  $sql .= " AND (sc.fk_user = ".((int) $user->id)." OR sc.fk_user IS NULL)";
1078  }
1079  } elseif (isModEnabled('multicompany')) {
1080  // If multicompany, and user is an internal user with all permissions, check that object is in correct entity
1081  $sql = "SELECT COUNT(dbt.".$dbt_select.") as nb";
1082  $sql .= " FROM ".MAIN_DB_PREFIX.$dbtablename." as dbt";
1083  $sql .= " WHERE dbt.".$dbt_select." IN (".$db->sanitize($objectid, 1).")";
1084  $sql .= " AND dbt.entity IN (".getEntity($sharedelement, 1).")";
1085  }
1086  }
1087 
1088  // For events, check on users assigned to event
1089  if ($feature === 'agenda' && $objectid > 0) {
1090  // Also check owner or attendee for users without allactions->read
1091  if ($objectid > 0 && empty($user->rights->agenda->allactions->read)) {
1092  require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php';
1093  $action = new ActionComm($db);
1094  $action->fetch($objectid);
1095  if ($action->authorid != $user->id && $action->userownerid != $user->id && !(array_key_exists($user->id, $action->userassigned))) {
1096  return false;
1097  }
1098  }
1099  }
1100 
1101  // For some object, we also have to check it is in the user hierarchy
1102  // Param $object must be the full object and not a simple id to have this test possible.
1103  if (in_array($feature, $checkhierarchy) && is_object($object) && $objectid > 0) {
1104  $childids = $user->getAllChildIds(1);
1105  $useridtocheck = 0;
1106  if ($feature == 'holiday') {
1107  $useridtocheck = $object->fk_user;
1108  if (!$user->hasRight('holiday', 'readall') && !in_array($useridtocheck, $childids) && !in_array($object->fk_validator, $childids)) {
1109  return false;
1110  }
1111  }
1112  if ($feature == 'expensereport') {
1113  $useridtocheck = $object->fk_user_author;
1114  if (!$user->hasRight('expensereport', 'readall') && !in_array($useridtocheck, $childids)) {
1115  return false;
1116  }
1117  }
1118  }
1119 
1120  // For some object, we also have to check it is public or owned by user
1121  // Param $object must be the full object and not a simple id to have this test possible.
1122  if (in_array($feature, $checkuser) && is_object($object) && $objectid > 0) {
1123  $useridtocheck = $object->fk_user;
1124  if (!empty($useridtocheck) && $useridtocheck > 0 && $useridtocheck != $user->id && empty($user->admin)) {
1125  return false;
1126  }
1127  }
1128 
1129  if ($sql) {
1130  $resql = $db->query($sql);
1131  if ($resql) {
1132  $obj = $db->fetch_object($resql);
1133  if (!$obj || $obj->nb < count(explode(',', $objectid))) { // error if we found 0 or less record than nb of id provided
1134  return false;
1135  }
1136  } else {
1137  dol_syslog("Bad forged sql in checkUserAccessToObject", LOG_WARNING);
1138  return false;
1139  }
1140  }
1141  }
1142 
1143  return true;
1144 }
1145 
1146 
1158 function httponly_accessforbidden($message = 1, $http_response_code = 403, $stringalreadysanitized = 0)
1159 {
1160  top_httphead();
1161  http_response_code($http_response_code);
1162 
1163  if ($stringalreadysanitized) {
1164  print $message;
1165  } else {
1166  print htmlentities($message);
1167  }
1168 
1169  exit(1);
1170 }
1171 
1185 function accessforbidden($message = '', $printheader = 1, $printfooter = 1, $showonlymessage = 0, $params = null)
1186 {
1187  global $conf, $db, $user, $langs, $hookmanager;
1188  global $action, $object;
1189 
1190  if (!is_object($langs)) {
1191  include_once DOL_DOCUMENT_ROOT.'/core/class/translate.class.php';
1192  $langs = new Translate('', $conf);
1193  $langs->setDefaultLang();
1194  }
1195 
1196  $langs->load("errors");
1197 
1198  if ($printheader) {
1199  if (function_exists("llxHeader")) {
1200  llxHeader('');
1201  } elseif (function_exists("llxHeaderVierge")) {
1202  llxHeaderVierge('');
1203  }
1204  }
1205  print '<div class="error">';
1206  if (empty($message)) {
1207  print $langs->trans("ErrorForbidden");
1208  } else {
1209  print $langs->trans($message);
1210  }
1211  print '</div>';
1212  print '<br>';
1213  if (empty($showonlymessage)) {
1214  if (empty($hookmanager)) {
1215  include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php';
1216  $hookmanager = new HookManager($db);
1217  // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
1218  $hookmanager->initHooks(array('main'));
1219  }
1220 
1221  $parameters = array('message'=>$message, 'params'=>$params);
1222  $reshook = $hookmanager->executeHooks('getAccessForbiddenMessage', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
1223  print $hookmanager->resPrint;
1224  if (empty($reshook)) {
1225  $langs->loadLangs(array("errors"));
1226  if ($user->login) {
1227  print $langs->trans("CurrentLogin").': <span class="error">'.$user->login.'</span><br>';
1228  print $langs->trans("ErrorForbidden2", $langs->transnoentitiesnoconv("Home"), $langs->transnoentitiesnoconv("Users"));
1229  print $langs->trans("ErrorForbidden4");
1230  } else {
1231  print $langs->trans("ErrorForbidden3");
1232  }
1233  }
1234  }
1235  if ($printfooter && function_exists("llxFooter")) {
1236  llxFooter();
1237  }
1238 
1239  exit(0);
1240 }
1241 
1242 
1250 {
1251  global $conf;
1252 
1253  $max = $conf->global->MAIN_UPLOAD_DOC; // In Kb
1254  $maxphp = @ini_get('upload_max_filesize'); // In unknown
1255  if (preg_match('/k$/i', $maxphp)) {
1256  $maxphp = preg_replace('/k$/i', '', $maxphp);
1257  $maxphp = $maxphp * 1;
1258  }
1259  if (preg_match('/m$/i', $maxphp)) {
1260  $maxphp = preg_replace('/m$/i', '', $maxphp);
1261  $maxphp = $maxphp * 1024;
1262  }
1263  if (preg_match('/g$/i', $maxphp)) {
1264  $maxphp = preg_replace('/g$/i', '', $maxphp);
1265  $maxphp = $maxphp * 1024 * 1024;
1266  }
1267  if (preg_match('/t$/i', $maxphp)) {
1268  $maxphp = preg_replace('/t$/i', '', $maxphp);
1269  $maxphp = $maxphp * 1024 * 1024 * 1024;
1270  }
1271  $maxphp2 = @ini_get('post_max_size'); // In unknown
1272  if (preg_match('/k$/i', $maxphp2)) {
1273  $maxphp2 = preg_replace('/k$/i', '', $maxphp2);
1274  $maxphp2 = $maxphp2 * 1;
1275  }
1276  if (preg_match('/m$/i', $maxphp2)) {
1277  $maxphp2 = preg_replace('/m$/i', '', $maxphp2);
1278  $maxphp2 = $maxphp2 * 1024;
1279  }
1280  if (preg_match('/g$/i', $maxphp2)) {
1281  $maxphp2 = preg_replace('/g$/i', '', $maxphp2);
1282  $maxphp2 = $maxphp2 * 1024 * 1024;
1283  }
1284  if (preg_match('/t$/i', $maxphp2)) {
1285  $maxphp2 = preg_replace('/t$/i', '', $maxphp2);
1286  $maxphp2 = $maxphp2 * 1024 * 1024 * 1024;
1287  }
1288  // Now $max and $maxphp and $maxphp2 are in Kb
1289  $maxmin = $max;
1290  $maxphptoshow = $maxphptoshowparam = '';
1291  if ($maxphp > 0) {
1292  $maxmin = min($maxmin, $maxphp);
1293  $maxphptoshow = $maxphp;
1294  $maxphptoshowparam = 'upload_max_filesize';
1295  }
1296  if ($maxphp2 > 0) {
1297  $maxmin = min($maxmin, $maxphp2);
1298  if ($maxphp2 < $maxphp) {
1299  $maxphptoshow = $maxphp2;
1300  $maxphptoshowparam = 'post_max_size';
1301  }
1302  }
1303  //var_dump($maxphp.'-'.$maxphp2);
1304  //var_dump($maxmin);
1305 
1306  return array('max'=>$max, 'maxmin'=>$maxmin, 'maxphptoshow'=>$maxphptoshow, 'maxphptoshowparam'=>$maxphptoshowparam);
1307 }
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:56
llxFooter()
Empty footer.
Definition: wrapper.php:70
Class to manage agenda events (actions)
Class to manage hooks.
Class to manage projects.
Class to manage tasks.
Definition: task.class.php:40
Class to manage translations.
Class to manage Dolibarr users.
Definition: user.class.php:48
if(isModEnabled('facture') && $user->hasRight('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') && $user->hasRight('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)) $sql
Social contributions to pay.
Definition: index.php:746
dol_print_error($db='', $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
dol_strlen($string, $stringencoding='UTF-8')
Make a strlen call.
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.
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:1510
dolEncrypt($chain, $key='', $ciphering='AES-256-CTR', $forceseed='')
Encode a string with a symetric encryption.
dolGetRandomBytes($length)
Return a string of random bytes (hexa string) with length = $length fro cryptographic purposes.
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.
httponly_accessforbidden($message=1, $http_response_code=403, $stringalreadysanitized=0)
Show a message to say access is forbidden and stop program.
dolDecrypt($chain, $key='')
Decode a string with a symetric encryption.
dol_hash($chain, $type='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.