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