dolibarr 19.0.4
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
38function 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
69function 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
100function 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
122function 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
181function 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
236function dol_hash($chain, $type = '0', $nosalt = 0)
237{
238 // No need to add salt for password_hash
239 if (($type == '0' || $type == 'auto') && getDolGlobalString('MAIN_SECURITY_HASH_ALGO') && getDolGlobalString('MAIN_SECURITY_HASH_ALGO') == 'password_hash' && function_exists('password_hash')) {
240 return password_hash($chain, PASSWORD_DEFAULT);
241 }
242
243 // Salt value
244 if (getDolGlobalString('MAIN_SECURITY_SALT') && $type != '4' && $type !== 'openldap' && empty($nosalt)) {
245 $chain = getDolGlobalString('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') { // For hashing with no need of security
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 (getDolGlobalString('MAIN_SECURITY_HASH_ALGO') == 'sha1') {
261 return sha1($chain);
262 } elseif (getDolGlobalString('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
282function dol_verifyHash($chain, $hash, $type = '0')
283{
284 if ($type == '0' && getDolGlobalString('MAIN_SECURITY_HASH_ALGO') && getDolGlobalString('MAIN_SECURITY_HASH_ALGO') == 'password_hash' && function_exists('password_verify')) {
285 if (! empty($hash[0]) && $hash[0] == '$') {
286 return password_verify($chain, $hash);
287 } elseif (dol_strlen($hash) == 32) {
288 return dol_verifyHash($chain, $hash, '3'); // md5
289 } elseif (dol_strlen($hash) == 40) {
290 return dol_verifyHash($chain, $hash, '2'); // sha1md5
291 }
292
293 return false;
294 }
295
296 return dol_hash($chain, $type) == $hash;
297}
298
306function dolGetLdapPasswordHash($password, $type = 'md5')
307{
308 if (empty($type)) {
309 $type = 'md5';
310 }
311
312 $salt = substr(sha1(time()), 0, 8);
313
314 if ($type === 'md5') {
315 return '{MD5}' . base64_encode(hash("md5", $password, true)); //For OpenLdap with md5 (based on an unencrypted password in base)
316 } elseif ($type === 'md5frommd5') {
317 return '{MD5}' . base64_encode(hex2bin($password)); // Create OpenLDAP MD5 password from Dolibarr MD5 password
318 } elseif ($type === 'smd5') {
319 return "{SMD5}" . base64_encode(hash("md5", $password . $salt, true) . $salt);
320 } elseif ($type === 'sha') {
321 return '{SHA}' . base64_encode(hash("sha1", $password, true));
322 } elseif ($type === 'ssha') {
323 return "{SSHA}" . base64_encode(hash("sha1", $password . $salt, true) . $salt);
324 } elseif ($type === 'sha256') {
325 return "{SHA256}" . base64_encode(hash("sha256", $password, true));
326 } elseif ($type === 'ssha256') {
327 return "{SSHA256}" . base64_encode(hash("sha256", $password . $salt, true) . $salt);
328 } elseif ($type === 'sha384') {
329 return "{SHA384}" . base64_encode(hash("sha384", $password, true));
330 } elseif ($type === 'ssha384') {
331 return "{SSHA384}" . base64_encode(hash("sha384", $password . $salt, true) . $salt);
332 } elseif ($type === 'sha512') {
333 return "{SHA512}" . base64_encode(hash("sha512", $password, true));
334 } elseif ($type === 'ssha512') {
335 return "{SSHA512}" . base64_encode(hash("sha512", $password . $salt, true) . $salt);
336 } elseif ($type === 'crypt') {
337 return '{CRYPT}' . crypt($password, $salt);
338 } elseif ($type === 'clear') {
339 return '{CLEAR}' . $password; // Just for test, plain text password is not secured !
340 }
341 return "";
342}
343
364function restrictedArea(User $user, $features, $object = 0, $tableandshare = '', $feature2 = '', $dbt_keyfield = 'fk_soc', $dbt_select = 'rowid', $isdraft = 0, $mode = 0)
365{
366 global $conf;
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\.\,]/', '', $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 if ($features == 'evaluation') {
448 $features = 'hrm';
449 $feature2 = 'evaluation';
450 }
451
452 //print $features.' - '.$tableandshare.' - '.$feature2.' - '.$dbt_select."\n";
453
454 // Get more permissions checks from hooks
455 $parameters = array('features'=>$features, 'originalfeatures'=>$originalfeatures, 'objectid'=>$objectid, 'dbt_select'=>$dbt_select, 'idtype'=>$dbt_select, 'isdraft'=>$isdraft);
456 if (!empty($hookmanager)) {
457 $reshook = $hookmanager->executeHooks('restrictedArea', $parameters);
458
459 if (isset($hookmanager->resArray['result'])) {
460 if ($hookmanager->resArray['result'] == 0) {
461 if ($mode) {
462 return 0;
463 } else {
464 accessforbidden(); // Module returns 0, so access forbidden
465 }
466 }
467 }
468 if ($reshook > 0) { // No other test done.
469 return 1;
470 }
471 }
472
473 // Features/modules to check
474 $featuresarray = array($features);
475 if (preg_match('/&/', $features)) {
476 $featuresarray = explode("&", $features);
477 } elseif (preg_match('/\|/', $features)) {
478 $featuresarray = explode("|", $features);
479 }
480
481 // More subfeatures to check
482 if (!empty($feature2)) {
483 $feature2 = explode("|", $feature2);
484 }
485
486 $listofmodules = explode(',', getDolGlobalString('MAIN_MODULES_FOR_EXTERNAL'));
487
488 // Check read permission from module
489 $readok = 1;
490 $nbko = 0;
491 foreach ($featuresarray as $feature) { // first we check nb of test ko
492 $featureforlistofmodule = $feature;
493 if ($featureforlistofmodule == 'produit') {
494 $featureforlistofmodule = 'product';
495 }
496 if ($featureforlistofmodule == 'supplier_proposal') {
497 $featureforlistofmodule = 'supplierproposal';
498 }
499 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
500 $readok = 0;
501 $nbko++;
502 continue;
503 }
504
505 if ($feature == 'societe' && (empty($feature2) || !in_array('contact', $feature2))) {
506 if (!$user->hasRight('societe', 'lire') && !$user->hasRight('fournisseur', 'lire')) {
507 $readok = 0;
508 $nbko++;
509 }
510 } elseif (($feature == 'societe' && (!empty($feature2) && in_array('contact', $feature2))) || $feature == 'contact') {
511 if (!$user->hasRight('societe', 'contact', 'lire')) {
512 $readok = 0;
513 $nbko++;
514 }
515 } elseif ($feature == 'produit|service') {
516 if (!$user->hasRight('produit', 'lire') && !$user->hasRight('service', 'lire')) {
517 $readok = 0;
518 $nbko++;
519 }
520 } elseif ($feature == 'prelevement') {
521 if (!$user->hasRight('prelevement', 'bons', 'lire')) {
522 $readok = 0;
523 $nbko++;
524 }
525 } elseif ($feature == 'cheque') {
526 if (!$user->hasRight('banque', 'cheque')) {
527 $readok = 0;
528 $nbko++;
529 }
530 } elseif ($feature == 'projet') {
531 if (!$user->hasRight('projet', 'lire') && !$user->hasRight('projet', 'all', 'lire')) {
532 $readok = 0;
533 $nbko++;
534 }
535 } elseif ($feature == 'payment') {
536 if (!$user->hasRight('facture', 'lire')) {
537 $readok = 0;
538 $nbko++;
539 }
540 } elseif ($feature == 'payment_supplier') {
541 if (!$user->hasRight('fournisseur', 'facture', 'lire')) {
542 $readok = 0;
543 $nbko++;
544 }
545 } elseif ($feature == 'payment_sc') {
546 if (!$user->hasRight('tax', 'charges', 'lire')) {
547 $readok = 0;
548 $nbko++;
549 }
550 } elseif (!empty($feature2)) { // This is for permissions on 2 levels (module->object->read)
551 $tmpreadok = 1;
552 foreach ($feature2 as $subfeature) {
553 if ($subfeature == 'user' && $user->id == $objectid) {
554 continue; // A user can always read its own card
555 }
556 if ($subfeature == 'fiscalyear' && $user->hasRight('accounting', 'fiscalyear', 'write')) {
557 // only one right for fiscalyear
558 $tmpreadok = 1;
559 continue;
560 }
561 if (!empty($subfeature) && !$user->hasRight($feature, $subfeature, 'lire') && !$user->hasRight($feature, $subfeature, 'read')) {
562 $tmpreadok = 0;
563 } elseif (empty($subfeature) && !$user->hasRight($feature, 'lire') && !$user->hasRight($feature, 'read')) {
564 $tmpreadok = 0;
565 } else {
566 $tmpreadok = 1;
567 break;
568 } // Break is to bypass second test if the first is ok
569 }
570 if (!$tmpreadok) { // We found a test on feature that is ko
571 $readok = 0; // All tests are ko (we manage here the and, the or will be managed later using $nbko).
572 $nbko++;
573 }
574 } elseif (!empty($feature) && ($feature != 'user' && $feature != 'usergroup')) { // This is permissions on 1 level (module->read)
575 if (!$user->hasRight($feature, 'lire')
576 && !$user->hasRight($feature, 'read')
577 && !$user->hasRight($feature, 'run')) {
578 $readok = 0;
579 $nbko++;
580 }
581 }
582 }
583
584 // If a or and at least one ok
585 if (preg_match('/\|/', $features) && $nbko < count($featuresarray)) {
586 $readok = 1;
587 }
588
589 if (!$readok) {
590 if ($mode) {
591 return 0;
592 } else {
594 }
595 }
596 //print "Read access is ok";
597
598 // Check write permission from module (we need to know write permission to create but also to delete drafts record or to upload files)
599 $createok = 1;
600 $nbko = 0;
601 $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));
602 $wemustcheckpermissionfordeletedraft = ((GETPOST("action", "aZ09") == 'confirm_delete' && GETPOST("confirm", "aZ09") == 'yes') || GETPOST("action", "aZ09") == 'delete');
603
604 if ($wemustcheckpermissionforcreate || $wemustcheckpermissionfordeletedraft) {
605 foreach ($featuresarray as $feature) {
606 if ($feature == 'contact') {
607 if (!$user->hasRight('societe', 'contact', 'creer')) {
608 $createok = 0;
609 $nbko++;
610 }
611 } elseif ($feature == 'produit|service') {
612 if (!$user->hasRight('produit', 'creer') && !$user->hasRight('service', 'creer')) {
613 $createok = 0;
614 $nbko++;
615 }
616 } elseif ($feature == 'prelevement') {
617 if (!$user->hasRight('prelevement', 'bons', 'creer')) {
618 $createok = 0;
619 $nbko++;
620 }
621 } elseif ($feature == 'commande_fournisseur') {
622 if (!$user->hasRight('fournisseur', 'commande', 'creer') || !$user->hasRight('supplier_order', 'creer')) {
623 $createok = 0;
624 $nbko++;
625 }
626 } elseif ($feature == 'banque') {
627 if (!$user->hasRight('banque', 'modifier')) {
628 $createok = 0;
629 $nbko++;
630 }
631 } elseif ($feature == 'cheque') {
632 if (!$user->hasRight('banque', 'cheque')) {
633 $createok = 0;
634 $nbko++;
635 }
636 } elseif ($feature == 'import') {
637 if (!$user->hasRight('import', 'run')) {
638 $createok = 0;
639 $nbko++;
640 }
641 } elseif ($feature == 'ecm') {
642 if (!$user->hasRight('ecm', 'upload')) {
643 $createok = 0;
644 $nbko++;
645 }
646 } elseif ($feature == 'modulebuilder') {
647 if (!$user->hasRight('modulebuilder', 'run')) {
648 $createok = 0;
649 $nbko++;
650 }
651 } elseif (!empty($feature2)) { // This is for permissions on 2 levels (module->object->write)
652 foreach ($feature2 as $subfeature) {
653 if ($subfeature == 'user' && $user->id == $objectid && $user->hasRight('user', 'self', 'creer')) {
654 continue; // User can edit its own card
655 }
656 if ($subfeature == 'user' && $user->id == $objectid && $user->hasRight('user', 'self', 'password')) {
657 continue; // User can edit its own password
658 }
659 if ($subfeature == 'user' && $user->id != $objectid && $user->hasRight('user', 'user', 'password')) {
660 continue; // User can edit another user's password
661 }
662
663 if (!$user->hasRight($feature, $subfeature, 'creer')
664 && !$user->hasRight($feature, $subfeature, 'write')
665 && !$user->hasRight($feature, $subfeature, 'create')) {
666 $createok = 0;
667 $nbko++;
668 } else {
669 $createok = 1;
670 // Break to bypass second test if the first is ok
671 break;
672 }
673 }
674 } elseif (!empty($feature)) { // This is for permissions on 1 levels (module->write)
675 //print '<br>feature='.$feature.' creer='.$user->rights->$feature->creer.' write='.$user->rights->$feature->write; exit;
676 if (!$user->hasRight($feature, 'creer')
677 && !$user->hasRight($feature, 'write')
678 && !$user->hasRight($feature, 'create')) {
679 $createok = 0;
680 $nbko++;
681 }
682 }
683 }
684
685 // If a or and at least one ok
686 if (preg_match('/\|/', $features) && $nbko < count($featuresarray)) {
687 $createok = 1;
688 }
689
690 if ($wemustcheckpermissionforcreate && !$createok) {
691 if ($mode) {
692 return 0;
693 } else {
695 }
696 }
697 //print "Write access is ok";
698 }
699
700 // Check create user permission
701 $createuserok = 1;
702 if (GETPOST('action', 'aZ09') == 'confirm_create_user' && GETPOST("confirm", 'aZ09') == 'yes') {
703 if (!$user->hasRight('user', 'user', 'creer')) {
704 $createuserok = 0;
705 }
706
707 if (!$createuserok) {
708 if ($mode) {
709 return 0;
710 } else {
712 }
713 }
714 //print "Create user access is ok";
715 }
716
717 // Check delete permission from module
718 $deleteok = 1;
719 $nbko = 0;
720 if ((GETPOST("action", "aZ09") == 'confirm_delete' && GETPOST("confirm", "aZ09") == 'yes') || GETPOST("action", "aZ09") == 'delete') {
721 foreach ($featuresarray as $feature) {
722 if ($feature == 'bookmark') {
723 if (!$user->hasRight('bookmark', 'supprimer')) {
724 if ($user->id != $object->fk_user || !$user->hasRight('bookmark', 'creer')) {
725 $deleteok = 0;
726 }
727 }
728 } elseif ($feature == 'contact') {
729 if (!$user->hasRight('societe', 'contact', 'supprimer')) {
730 $deleteok = 0;
731 }
732 } elseif ($feature == 'produit|service') {
733 if (!$user->hasRight('produit', 'supprimer') && !$user->hasRight('service', 'supprimer')) {
734 $deleteok = 0;
735 }
736 } elseif ($feature == 'commande_fournisseur') {
737 if (!$user->hasRight('fournisseur', 'commande', 'supprimer')) {
738 $deleteok = 0;
739 }
740 } elseif ($feature == 'payment_supplier') { // Permission to delete a payment of an invoice is permission to edit an invoice.
741 if (!$user->hasRight('fournisseur', 'facture', 'creer')) {
742 $deleteok = 0;
743 }
744 } elseif ($feature == 'payment') {
745 if (!$user->hasRight('facture', 'paiement')) {
746 $deleteok = 0;
747 }
748 } elseif ($feature == 'payment_sc') {
749 if (!$user->hasRight('tax', 'charges', 'creer')) {
750 $deleteok = 0;
751 }
752 } elseif ($feature == 'banque') {
753 if (!$user->hasRight('banque', 'modifier')) {
754 $deleteok = 0;
755 }
756 } elseif ($feature == 'cheque') {
757 if (!$user->hasRight('banque', 'cheque')) {
758 $deleteok = 0;
759 }
760 } elseif ($feature == 'ecm') {
761 if (!$user->hasRight('ecm', 'upload')) {
762 $deleteok = 0;
763 }
764 } elseif ($feature == 'ftp') {
765 if (!$user->hasRight('ftp', 'write')) {
766 $deleteok = 0;
767 }
768 } elseif ($feature == 'salaries') {
769 if (!$user->hasRight('salaries', 'delete')) {
770 $deleteok = 0;
771 }
772 } elseif ($feature == 'adherent') {
773 if (!$user->hasRight('adherent', 'supprimer')) {
774 $deleteok = 0;
775 }
776 } elseif ($feature == 'paymentbybanktransfer') {
777 if (!$user->hasRight('paymentbybanktransfer', 'create')) { // There is no delete permission
778 $deleteok = 0;
779 }
780 } elseif ($feature == 'prelevement') {
781 if (!$user->hasRight('prelevement', 'bons', 'creer')) { // There is no delete permission
782 $deleteok = 0;
783 }
784 } elseif (!empty($feature2)) { // This is for permissions on 2 levels
785 foreach ($feature2 as $subfeature) {
786 if (!$user->hasRight($feature, $subfeature, 'supprimer') && !$user->hasRight($feature, $subfeature, 'delete')) {
787 $deleteok = 0;
788 } else {
789 $deleteok = 1;
790 break;
791 } // For bypass the second test if the first is ok
792 }
793 } elseif (!empty($feature)) { // This is used for permissions on 1 level
794 //print '<br>feature='.$feature.' creer='.$user->rights->$feature->supprimer.' write='.$user->rights->$feature->delete;
795 if (!$user->hasRight($feature, 'supprimer')
796 && !$user->hasRight($feature, 'delete')
797 && !$user->hasRight($feature, 'run')) {
798 $deleteok = 0;
799 }
800 }
801 }
802
803 // If a or and at least one ok
804 if (preg_match('/\|/', $features) && $nbko < count($featuresarray)) {
805 $deleteok = 1;
806 }
807
808 if (!$deleteok && !($isdraft && $createok)) {
809 if ($mode) {
810 return 0;
811 } else {
813 }
814 }
815 //print "Delete access is ok";
816 }
817
818 // If we have a particular object to check permissions on, we check if $user has permission
819 // for this given object (link to company, is contact for project, ...)
820 if (!empty($objectid) && $objectid > 0) {
821 $ok = checkUserAccessToObject($user, $featuresarray, $object, $tableandshare, $feature2, $dbt_keyfield, $dbt_select, $parentfortableentity);
822 $params = array('objectid' => $objectid, 'features' => join(',', $featuresarray), 'features2' => $feature2);
823 //print 'checkUserAccessToObject ok='.$ok;
824 if ($mode) {
825 return $ok ? 1 : 0;
826 } else {
827 if ($ok) {
828 return 1;
829 } else {
830 accessforbidden('', 1, 1, 0, $params);
831 }
832 }
833 }
834
835 return 1;
836}
837
853function checkUserAccessToObject($user, array $featuresarray, $object = 0, $tableandshare = '', $feature2 = '', $dbt_keyfield = '', $dbt_select = 'rowid', $parenttableforentity = '')
854{
855 global $db, $conf;
856
857 if (is_object($object)) {
858 $objectid = $object->id;
859 } else {
860 $objectid = $object; // $objectid can be X or 'X,Y,Z'
861 }
862 $objectid = preg_replace('/[^0-9\.\,]/', '', $objectid); // For the case value is coming from a non sanitized user input
863
864 //dol_syslog("functions.lib:restrictedArea $feature, $objectid, $dbtablename, $feature2, $dbt_socfield, $dbt_select, $isdraft");
865 //print "user_id=".$user->id.", features=".join(',', $featuresarray).", objectid=".$objectid;
866 //print ", tableandshare=".$tableandshare.", dbt_socfield=".$dbt_keyfield.", dbt_select=".$dbt_select."<br>";
867
868 // More parameters
869 $params = explode('&', $tableandshare);
870 $dbtablename = (!empty($params[0]) ? $params[0] : '');
871 $sharedelement = (!empty($params[1]) ? $params[1] : $dbtablename);
872
873 foreach ($featuresarray as $feature) {
874 $sql = '';
875
876 //var_dump($feature);exit;
877
878 // For backward compatibility
879 if ($feature == 'societe' && !empty($feature2) && is_array($feature2) && in_array('contact', $feature2)) {
880 $feature = 'contact';
881 $feature2 = '';
882 }
883 if ($feature == 'member') {
884 $feature = 'adherent';
885 }
886 if ($feature == 'project') {
887 $feature = 'projet';
888 }
889 if ($feature == 'projet' && !empty($feature2) && is_array($feature2) && !empty(array_intersect(array('project_task', 'projet_task'), $feature2))) {
890 $feature = 'project_task';
891 }
892 if ($feature == 'task' || $feature == 'projet_task') {
893 $feature = 'project_task';
894 }
895 if ($feature == 'eventorganization') {
896 $feature = 'agenda';
897 $dbtablename = 'actioncomm';
898 }
899 if ($feature == 'payment_sc' && empty($parenttableforentity)) {
900 // If we check perm on payment page but $parenttableforentity not defined, we force value on parent table
901 $parenttableforentity = '';
902 $dbtablename = "chargesociales";
903 $feature = "chargesociales";
904 $objectid = $object->fk_charge;
905 }
906
907 $checkonentitydone = 0;
908
909 // Array to define rules of checks to do
910 $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)
911 $checksoc = array('societe'); // Test for object Societe
912 $checkparentsoc = array('agenda', 'contact', 'contrat'); // Test on entity + link to third party on field $dbt_keyfield. Allowed if link is empty (Ex: contacts...).
913 $checkproject = array('projet', 'project'); // Test for project object
914 $checktask = array('projet_task', 'project_task'); // Test for task object
915 $checkhierarchy = array('expensereport', 'holiday', 'hrm'); // check permission among the hierarchy of user
916 $checkuser = array('bookmark'); // check permission among the fk_user (must be myself or null)
917 $nocheck = array('barcode', 'stock'); // No test
918
919 //$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...).
920
921 // If dbtablename not defined, we use same name for table than module name
922 if (empty($dbtablename)) {
923 $dbtablename = $feature;
924 $sharedelement = (!empty($params[1]) ? $params[1] : $dbtablename); // We change dbtablename, so we set sharedelement too.
925 }
926
927 // To avoid an access forbidden with a numeric ref
928 if ($dbt_select != 'rowid' && $dbt_select != 'id') {
929 $objectid = "'".$objectid."'"; // Note: $objectid was already cast into int at begin of this method.
930 }
931 // Check permission for objectid on entity only
932 if (in_array($feature, $check) && $objectid > 0) { // For $objectid = 0, no check
933 $sql = "SELECT COUNT(dbt.".$dbt_select.") as nb";
934 $sql .= " FROM ".MAIN_DB_PREFIX.$dbtablename." as dbt";
935 if (($feature == 'user' || $feature == 'usergroup') && isModEnabled('multicompany')) { // Special for multicompany
936 if (getDolGlobalString('MULTICOMPANY_TRANSVERSE_MODE')) {
937 if ($conf->entity == 1 && $user->admin && !$user->entity) {
938 $sql .= " WHERE dbt.".$dbt_select." IN (".$db->sanitize($objectid, 1).")";
939 $sql .= " AND dbt.entity IS NOT NULL";
940 } else {
941 $sql .= ",".MAIN_DB_PREFIX."usergroup_user as ug";
942 $sql .= " WHERE dbt.".$dbt_select." IN (".$db->sanitize($objectid, 1).")";
943 $sql .= " AND ((ug.fk_user = dbt.rowid";
944 $sql .= " AND ug.entity IN (".getEntity('usergroup')."))";
945 $sql .= " OR dbt.entity = 0)"; // Show always superadmin
946 }
947 } else {
948 $sql .= " WHERE dbt.".$dbt_select." IN (".$db->sanitize($objectid, 1).")";
949 $sql .= " AND dbt.entity IN (".getEntity($sharedelement, 1).")";
950 }
951 } else {
952 $reg = array();
953 if ($parenttableforentity && preg_match('/(.*)@(.*)/', $parenttableforentity, $reg)) {
954 $sql .= ", ".MAIN_DB_PREFIX.$reg[2]." as dbtp";
955 $sql .= " WHERE dbt.".$reg[1]." = dbtp.rowid AND dbt.".$dbt_select." IN (".$db->sanitize($objectid, 1).")";
956 $sql .= " AND dbtp.entity IN (".getEntity($sharedelement, 1).")";
957 } else {
958 $sql .= " WHERE dbt.".$dbt_select." IN (".$db->sanitize($objectid, 1).")";
959 $sql .= " AND dbt.entity IN (".getEntity($sharedelement, 1).")";
960 }
961 }
962 $checkonentitydone = 1;
963 }
964 if (in_array($feature, $checksoc) && $objectid > 0) { // We check feature = checksoc. For $objectid = 0, no check
965 // If external user: Check permission for external users
966 if ($user->socid > 0) {
967 if ($user->socid != $objectid) {
968 return false;
969 }
970 } elseif (isModEnabled("societe") && ($user->hasRight('societe', 'lire') && !$user->hasRight('societe', 'client', 'voir'))) {
971 // If internal user: Check permission for internal users that are restricted on their objects
972 $sql = "SELECT COUNT(sc.fk_soc) as nb";
973 $sql .= " FROM (".MAIN_DB_PREFIX."societe_commerciaux as sc";
974 $sql .= ", ".MAIN_DB_PREFIX."societe as s)";
975 $sql .= " WHERE sc.fk_soc IN (".$db->sanitize($objectid, 1).")";
976 $sql .= " AND sc.fk_user = ".((int) $user->id);
977 $sql .= " AND sc.fk_soc = s.rowid";
978 $sql .= " AND s.entity IN (".getEntity($sharedelement, 1).")";
979 } elseif (isModEnabled('multicompany')) {
980 // If multicompany and internal users with all permissions, check user is in correct entity
981 $sql = "SELECT COUNT(s.rowid) as nb";
982 $sql .= " FROM ".MAIN_DB_PREFIX."societe as s";
983 $sql .= " WHERE s.rowid IN (".$db->sanitize($objectid, 1).")";
984 $sql .= " AND s.entity IN (".getEntity($sharedelement, 1).")";
985 }
986
987 $checkonentitydone = 1;
988 }
989 if (in_array($feature, $checkparentsoc) && $objectid > 0) { // Test on entity + link to thirdparty. Allowed if link is empty (Ex: contacts...).
990 // If external user: Check permission for external users
991 if ($user->socid > 0) {
992 $sql = "SELECT COUNT(dbt.".$dbt_select.") as nb";
993 $sql .= " FROM ".MAIN_DB_PREFIX.$dbtablename." as dbt";
994 $sql .= " WHERE dbt.".$dbt_select." IN (".$db->sanitize($objectid, 1).")";
995 $sql .= " AND dbt.fk_soc = ".((int) $user->socid);
996 } elseif (isModEnabled("societe") && ($user->hasRight('societe', 'lire') && !$user->hasRight('societe', 'client', 'voir'))) {
997 // If internal user: Check permission for internal users that are restricted on their objects
998 $sql = "SELECT COUNT(dbt.".$dbt_select.") as nb";
999 $sql .= " FROM ".MAIN_DB_PREFIX.$dbtablename." as dbt";
1000 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON dbt.fk_soc = sc.fk_soc AND sc.fk_user = ".((int) $user->id);
1001 $sql .= " WHERE dbt.".$dbt_select." IN (".$db->sanitize($objectid, 1).")";
1002 $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
1003 $sql .= " AND dbt.entity IN (".getEntity($sharedelement, 1).")";
1004 } elseif (isModEnabled('multicompany')) {
1005 // If multicompany and internal users with all permissions, check user is in correct entity
1006 $sql = "SELECT COUNT(dbt.".$dbt_select.") as nb";
1007 $sql .= " FROM ".MAIN_DB_PREFIX.$dbtablename." as dbt";
1008 $sql .= " WHERE dbt.".$dbt_select." IN (".$db->sanitize($objectid, 1).")";
1009 $sql .= " AND dbt.entity IN (".getEntity($sharedelement, 1).")";
1010 }
1011
1012 $checkonentitydone = 1;
1013 }
1014 if (in_array($feature, $checkproject) && $objectid > 0) {
1015 if (isModEnabled('project') && !$user->hasRight('projet', 'all', 'lire')) {
1016 $projectid = $objectid;
1017
1018 include_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
1019 $projectstatic = new Project($db);
1020 $tmps = $projectstatic->getProjectsAuthorizedForUser($user, 0, 1, 0);
1021
1022 $tmparray = explode(',', $tmps);
1023 if (!in_array($projectid, $tmparray)) {
1024 return false;
1025 }
1026 } else {
1027 $sql = "SELECT COUNT(dbt.".$dbt_select.") as nb";
1028 $sql .= " FROM ".MAIN_DB_PREFIX.$dbtablename." as dbt";
1029 $sql .= " WHERE dbt.".$dbt_select." IN (".$db->sanitize($objectid, 1).")";
1030 $sql .= " AND dbt.entity IN (".getEntity($sharedelement, 1).")";
1031 }
1032 $checkonentitydone = 1;
1033 }
1034 if (in_array($feature, $checktask) && $objectid > 0) {
1035 if (isModEnabled('project') && !$user->hasRight('projet', 'all', 'lire')) {
1036 $task = new Task($db);
1037 $task->fetch($objectid);
1038 $projectid = $task->fk_project;
1039
1040 include_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
1041 $projectstatic = new Project($db);
1042 $tmps = $projectstatic->getProjectsAuthorizedForUser($user, 0, 1, 0);
1043
1044 $tmparray = explode(',', $tmps);
1045 if (!in_array($projectid, $tmparray)) {
1046 return false;
1047 }
1048 } else {
1049 $sharedelement = 'project'; // for multicompany compatibility
1050 $sql = "SELECT COUNT(dbt.".$dbt_select.") as nb";
1051 $sql .= " FROM ".MAIN_DB_PREFIX.$dbtablename." as dbt";
1052 $sql .= " WHERE dbt.".$dbt_select." IN (".$db->sanitize($objectid, 1).")";
1053 $sql .= " AND dbt.entity IN (".getEntity($sharedelement, 1).")";
1054 }
1055
1056 $checkonentitydone = 1;
1057 }
1058 //var_dump($sql);
1059
1060 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
1061 // If external user: Check permission for external users
1062 if ($user->socid > 0) {
1063 if (empty($dbt_keyfield)) {
1064 dol_print_error('', 'Param dbt_keyfield is required but not defined');
1065 }
1066 $sql = "SELECT COUNT(dbt.".$dbt_keyfield.") as nb";
1067 $sql .= " FROM ".MAIN_DB_PREFIX.$dbtablename." as dbt";
1068 $sql .= " WHERE dbt.rowid IN (".$db->sanitize($objectid, 1).")";
1069 $sql .= " AND dbt.".$dbt_keyfield." = ".((int) $user->socid);
1070 } elseif (isModEnabled("societe") && !$user->hasRight('societe', 'client', 'voir')) {
1071 // If internal user without permission to see all thirdparties: Check permission for internal users that are restricted on their objects
1072 if ($feature != 'ticket') {
1073 if (empty($dbt_keyfield)) {
1074 dol_print_error('', 'Param dbt_keyfield is required but not defined');
1075 }
1076 $sql = "SELECT COUNT(sc.fk_soc) as nb";
1077 $sql .= " FROM ".MAIN_DB_PREFIX.$dbtablename." as dbt";
1078 $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
1079 $sql .= " WHERE dbt.".$dbt_select." IN (".$db->sanitize($objectid, 1).")";
1080 $sql .= " AND dbt.entity IN (".getEntity($sharedelement, 1).")";
1081 $sql .= " AND sc.fk_soc = dbt.".$dbt_keyfield;
1082 $sql .= " AND sc.fk_user = ".((int) $user->id);
1083 } else {
1084 // On ticket, the thirdparty is not mandatory, so we need a special test to accept record with no thirdparties.
1085 $sql = "SELECT COUNT(dbt.".$dbt_select.") as nb";
1086 $sql .= " FROM ".MAIN_DB_PREFIX.$dbtablename." as dbt";
1087 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON sc.fk_soc = dbt.".$dbt_keyfield." AND sc.fk_user = ".((int) $user->id);
1088 $sql .= " WHERE dbt.".$dbt_select." IN (".$db->sanitize($objectid, 1).")";
1089 $sql .= " AND dbt.entity IN (".getEntity($sharedelement, 1).")";
1090 $sql .= " AND (sc.fk_user = ".((int) $user->id)." OR sc.fk_user IS NULL)";
1091 }
1092 } elseif (isModEnabled('multicompany')) {
1093 // If multicompany, and user is an internal user with all permissions, check that object is in correct entity
1094 $sql = "SELECT COUNT(dbt.".$dbt_select.") as nb";
1095 $sql .= " FROM ".MAIN_DB_PREFIX.$dbtablename." as dbt";
1096 $sql .= " WHERE dbt.".$dbt_select." IN (".$db->sanitize($objectid, 1).")";
1097 $sql .= " AND dbt.entity IN (".getEntity($sharedelement, 1).")";
1098 }
1099 }
1100
1101 // For events, check on users assigned to event
1102 if ($feature === 'agenda' && $objectid > 0) {
1103 // Also check owner or attendee for users without allactions->read
1104 if ($objectid > 0 && !$user->hasRight('agenda', 'allactions', 'read')) {
1105 require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php';
1106 $action = new ActionComm($db);
1107 $action->fetch($objectid);
1108 if ($action->authorid != $user->id && $action->userownerid != $user->id && !(array_key_exists($user->id, $action->userassigned))) {
1109 return false;
1110 }
1111 }
1112 }
1113
1114 // For some object, we also have to check it is in the user hierarchy
1115 // Param $object must be the full object and not a simple id to have this test possible.
1116 if (in_array($feature, $checkhierarchy) && is_object($object) && $objectid > 0) {
1117 $childids = $user->getAllChildIds(1);
1118 $useridtocheck = 0;
1119 if ($feature == 'holiday') {
1120 $useridtocheck = $object->fk_user;
1121 if (!$user->hasRight('holiday', 'readall') && !in_array($useridtocheck, $childids) && !in_array($object->fk_validator, $childids)) {
1122 return false;
1123 }
1124 }
1125 if ($feature == 'expensereport') {
1126 $useridtocheck = $object->fk_user_author;
1127 if (!$user->hasRight('expensereport', 'readall')) {
1128 if (!in_array($useridtocheck, $childids)) {
1129 return false;
1130 }
1131 }
1132 }
1133 if ($feature == 'hrm' && in_array('evaluation', $feature2)) {
1134 $useridtocheck = $object->fk_user;
1135
1136 if ($user->hasRight('hrm', 'evaluation', 'readall')) {
1137 // the user can view evaluations for anyone
1138 return true;
1139 }
1140 if (!$user->hasRight('hrm', 'evaluation', 'read')) {
1141 // the user can't view any evaluations
1142 return false;
1143 }
1144 // the user can only their own evaluations or their subordinates'
1145 return in_array($useridtocheck, $childids);
1146 }
1147 }
1148
1149 // For some object, we also have to check it is public or owned by user
1150 // Param $object must be the full object and not a simple id to have this test possible.
1151 if (in_array($feature, $checkuser) && is_object($object) && $objectid > 0) {
1152 $useridtocheck = $object->fk_user;
1153 if (!empty($useridtocheck) && $useridtocheck > 0 && $useridtocheck != $user->id && empty($user->admin)) {
1154 return false;
1155 }
1156 }
1157
1158 if ($sql) {
1159 $resql = $db->query($sql);
1160 if ($resql) {
1161 $obj = $db->fetch_object($resql);
1162 if (!$obj || $obj->nb < count(explode(',', $objectid))) { // error if we found 0 or less record than nb of id provided
1163 return false;
1164 }
1165 } else {
1166 dol_syslog("Bad forged sql in checkUserAccessToObject", LOG_WARNING);
1167 return false;
1168 }
1169 }
1170 }
1171
1172 return true;
1173}
1174
1175
1187function httponly_accessforbidden($message = 1, $http_response_code = 403, $stringalreadysanitized = 0)
1188{
1189 top_httphead();
1190 http_response_code($http_response_code);
1191
1192 if ($stringalreadysanitized) {
1193 print $message;
1194 } else {
1195 print htmlentities($message);
1196 }
1197
1198 exit(1);
1199}
1200
1214function accessforbidden($message = '', $printheader = 1, $printfooter = 1, $showonlymessage = 0, $params = null)
1215{
1216 global $conf, $db, $user, $langs, $hookmanager;
1217 global $action, $object;
1218
1219 if (!is_object($langs)) {
1220 include_once DOL_DOCUMENT_ROOT.'/core/class/translate.class.php';
1221 $langs = new Translate('', $conf);
1222 $langs->setDefaultLang();
1223 }
1224
1225 $langs->loadLangs(array("main", "errors"));
1226
1227 if ($printheader) {
1228 if (function_exists("llxHeader")) {
1229 llxHeader('');
1230 } elseif (function_exists("llxHeaderVierge")) {
1231 llxHeaderVierge('');
1232 }
1233 print '<div style="padding: 20px">';
1234 }
1235 print '<div class="error">';
1236 if (empty($message)) {
1237 print $langs->trans("ErrorForbidden");
1238 } else {
1239 print $langs->trans($message);
1240 }
1241 print '</div>';
1242 print '<br>';
1243 if (empty($showonlymessage)) {
1244 if (empty($hookmanager)) {
1245 include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php';
1246 $hookmanager = new HookManager($db);
1247 // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
1248 $hookmanager->initHooks(array('main'));
1249 }
1250
1251 $parameters = array('message'=>$message, 'params'=>$params);
1252 $reshook = $hookmanager->executeHooks('getAccessForbiddenMessage', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
1253 print $hookmanager->resPrint;
1254 if (empty($reshook)) {
1255 $langs->loadLangs(array("errors"));
1256 if ($user->login) {
1257 print $langs->trans("CurrentLogin").': <span class="error">'.$user->login.'</span><br>';
1258 print $langs->trans("ErrorForbidden2", $langs->transnoentitiesnoconv("Home"), $langs->transnoentitiesnoconv("Users"));
1259 print $langs->trans("ErrorForbidden4");
1260 } else {
1261 print $langs->trans("ErrorForbidden3");
1262 }
1263 }
1264 }
1265 if ($printfooter && function_exists("llxFooter")) {
1266 print '</div>';
1267 llxFooter();
1268 }
1269
1270 exit(0);
1271}
1272
1273
1281{
1282 global $conf;
1283
1284 $max = $conf->global->MAIN_UPLOAD_DOC; // In Kb
1285 $maxphp = @ini_get('upload_max_filesize'); // In unknown
1286 if (preg_match('/k$/i', $maxphp)) {
1287 $maxphp = preg_replace('/k$/i', '', $maxphp);
1288 $maxphp = $maxphp * 1;
1289 }
1290 if (preg_match('/m$/i', $maxphp)) {
1291 $maxphp = preg_replace('/m$/i', '', $maxphp);
1292 $maxphp = $maxphp * 1024;
1293 }
1294 if (preg_match('/g$/i', $maxphp)) {
1295 $maxphp = preg_replace('/g$/i', '', $maxphp);
1296 $maxphp = $maxphp * 1024 * 1024;
1297 }
1298 if (preg_match('/t$/i', $maxphp)) {
1299 $maxphp = preg_replace('/t$/i', '', $maxphp);
1300 $maxphp = $maxphp * 1024 * 1024 * 1024;
1301 }
1302 $maxphp2 = @ini_get('post_max_size'); // In unknown
1303 if (preg_match('/k$/i', $maxphp2)) {
1304 $maxphp2 = preg_replace('/k$/i', '', $maxphp2);
1305 $maxphp2 = $maxphp2 * 1;
1306 }
1307 if (preg_match('/m$/i', $maxphp2)) {
1308 $maxphp2 = preg_replace('/m$/i', '', $maxphp2);
1309 $maxphp2 = $maxphp2 * 1024;
1310 }
1311 if (preg_match('/g$/i', $maxphp2)) {
1312 $maxphp2 = preg_replace('/g$/i', '', $maxphp2);
1313 $maxphp2 = $maxphp2 * 1024 * 1024;
1314 }
1315 if (preg_match('/t$/i', $maxphp2)) {
1316 $maxphp2 = preg_replace('/t$/i', '', $maxphp2);
1317 $maxphp2 = $maxphp2 * 1024 * 1024 * 1024;
1318 }
1319 // Now $max and $maxphp and $maxphp2 are in Kb
1320 $maxmin = $max;
1321 $maxphptoshow = $maxphptoshowparam = '';
1322 if ($maxphp > 0) {
1323 $maxmin = min($maxmin, $maxphp);
1324 $maxphptoshow = $maxphp;
1325 $maxphptoshowparam = 'upload_max_filesize';
1326 }
1327 if ($maxphp2 > 0) {
1328 $maxmin = min($maxmin, $maxphp2);
1329 if ($maxphp2 < $maxphp) {
1330 $maxphptoshow = $maxphp2;
1331 $maxphptoshowparam = 'post_max_size';
1332 }
1333 }
1334 //var_dump($maxphp.'-'.$maxphp2);
1335 //var_dump($maxmin);
1336
1337 return array('max'=>$max, 'maxmin'=>$maxmin, 'maxphptoshow'=>$maxphptoshow, 'maxphptoshowparam'=>$maxphptoshowparam);
1338}
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.
Class to manage translations.
Class to manage Dolibarr users.
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.
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.
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', $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.