dolibarr 21.0.0-alpha
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 if (strpos($chain, "\0") !== false) {
245 // String contains a null character that can't be encoded. Return an error instead of fatal error.
246 return 'Invalid string to encrypt. Contains a null character.';
247 }
248 return password_hash($chain, PASSWORD_DEFAULT);
249 }
250
251 // Salt value
252 if (getDolGlobalString('MAIN_SECURITY_SALT') && $type != '4' && $type !== 'openldap' && empty($nosalt)) {
253 $chain = getDolGlobalString('MAIN_SECURITY_SALT') . $chain;
254 }
255
256 if ($type == '1' || $type == 'sha1') {
257 return sha1($chain);
258 } elseif ($type == '2' || $type == 'sha1md5') {
259 return sha1(md5($chain));
260 } elseif ($type == '3' || $type == 'md5') { // For hashing with no need of security
261 return md5($chain);
262 } elseif ($type == '4' || $type == 'openldap') {
263 return dolGetLdapPasswordHash($chain, getDolGlobalString('LDAP_PASSWORD_HASH_TYPE', 'md5'));
264 } elseif ($type == '5' || $type == 'sha256') {
265 return hash('sha256', $chain);
266 } elseif ($type == '6' || $type == 'password_hash') {
267 return password_hash($chain, PASSWORD_DEFAULT);
268 } elseif (getDolGlobalString('MAIN_SECURITY_HASH_ALGO') == 'sha1') {
269 return sha1($chain);
270 } elseif (getDolGlobalString('MAIN_SECURITY_HASH_ALGO') == 'sha1md5') {
271 return sha1(md5($chain));
272 }
273
274 // No particular encoding defined, use default
275 return md5($chain);
276}
277
290function dol_verifyHash($chain, $hash, $type = '0')
291{
292 if ($type == '0' && getDolGlobalString('MAIN_SECURITY_HASH_ALGO') && getDolGlobalString('MAIN_SECURITY_HASH_ALGO') == 'password_hash' && function_exists('password_verify')) {
293 if (! empty($hash[0]) && $hash[0] == '$') {
294 return password_verify($chain, $hash);
295 } elseif (dol_strlen($hash) == 32) {
296 return dol_verifyHash($chain, $hash, '3'); // md5
297 } elseif (dol_strlen($hash) == 40) {
298 return dol_verifyHash($chain, $hash, '2'); // sha1md5
299 }
300
301 return false;
302 }
303
304 return dol_hash($chain, $type) == $hash;
305}
306
314function dolGetLdapPasswordHash($password, $type = 'md5')
315{
316 if (empty($type)) {
317 $type = 'md5';
318 }
319
320 $salt = substr(sha1((string) time()), 0, 8);
321
322 if ($type === 'md5') {
323 return '{MD5}' . base64_encode(hash("md5", $password, true)); //For OpenLdap with md5 (based on an unencrypted password in base)
324 } elseif ($type === 'md5frommd5') {
325 return '{MD5}' . base64_encode(hex2bin($password)); // Create OpenLDAP MD5 password from Dolibarr MD5 password
326 } elseif ($type === 'smd5') {
327 return "{SMD5}" . base64_encode(hash("md5", $password . $salt, true) . $salt);
328 } elseif ($type === 'sha') {
329 return '{SHA}' . base64_encode(hash("sha1", $password, true));
330 } elseif ($type === 'ssha') {
331 return "{SSHA}" . base64_encode(hash("sha1", $password . $salt, true) . $salt);
332 } elseif ($type === 'sha256') {
333 return "{SHA256}" . base64_encode(hash("sha256", $password, true));
334 } elseif ($type === 'ssha256') {
335 return "{SSHA256}" . base64_encode(hash("sha256", $password . $salt, true) . $salt);
336 } elseif ($type === 'sha384') {
337 return "{SHA384}" . base64_encode(hash("sha384", $password, true));
338 } elseif ($type === 'ssha384') {
339 return "{SSHA384}" . base64_encode(hash("sha384", $password . $salt, true) . $salt);
340 } elseif ($type === 'sha512') {
341 return "{SHA512}" . base64_encode(hash("sha512", $password, true));
342 } elseif ($type === 'ssha512') {
343 return "{SSHA512}" . base64_encode(hash("sha512", $password . $salt, true) . $salt);
344 } elseif ($type === 'crypt') {
345 return '{CRYPT}' . crypt($password, $salt);
346 } elseif ($type === 'clear') {
347 return '{CLEAR}' . $password; // Just for test, plain text password is not secured !
348 }
349 return "";
350}
351
372function restrictedArea(User $user, $features, $object = 0, $tableandshare = '', $feature2 = '', $dbt_keyfield = 'fk_soc', $dbt_select = 'rowid', $isdraft = 0, $mode = 0)
373{
374 global $hookmanager;
375
376 // Define $objectid
377 if (is_object($object)) {
378 $objectid = $object->id;
379 } else {
380 $objectid = $object; // $objectid can be X or 'X,Y,Z'
381 }
382 if ($objectid == "-1") {
383 $objectid = 0;
384 }
385 if ($objectid) {
386 $objectid = preg_replace('/[^0-9\.\,]/', '', (string) $objectid); // For the case value is coming from a non sanitized user input
387 }
388
389 //dol_syslog("functions.lib:restrictedArea $feature, $objectid, $dbtablename, $feature2, $dbt_socfield, $dbt_select, $isdraft");
390 /*print "user_id=".$user->id.", features=".$features.", feature2=".$feature2.", objectid=".$objectid;
391 print ", dbtablename=".$tableandshare.", dbt_socfield=".$dbt_keyfield.", dbt_select=".$dbt_select;
392 print ", perm: user->hasRight(".$features.($feature2 ? ",".$feature2 : "").", lire) = ".($feature2 ? $user->hasRight($features, $feature2, 'lire') : $user->hasRight($features, 'lire'))."<br>";
393 */
394
395 $parentfortableentity = '';
396
397 // Fix syntax of $features param to support non standard module names.
398 $originalfeatures = $features;
399 if ($features == 'agenda') {
400 $tableandshare = 'actioncomm&societe';
401 $feature2 = 'myactions|allactions';
402 $dbt_select = 'id';
403 }
404 if ($features == 'bank') {
405 $features = 'banque';
406 }
407 if ($features == 'facturerec') {
408 $features = 'facture';
409 }
410 if ($features == 'supplier_invoicerec') {
411 $features = 'fournisseur';
412 $feature2 = 'facture';
413 }
414 if ($features == 'mo') {
415 $features = 'mrp';
416 }
417 if ($features == 'member') {
418 $features = 'adherent';
419 }
420 if ($features == 'subscription') {
421 $features = 'adherent';
422 $feature2 = 'cotisation';
423 }
424 if ($features == 'website' && is_object($object) && $object->element == 'websitepage') {
425 $parentfortableentity = 'fk_website@website';
426 }
427 if ($features == 'project') {
428 $features = 'projet';
429 }
430 if ($features == 'product') {
431 $features = 'produit';
432 }
433 if ($features == 'productbatch') {
434 $features = 'produit';
435 }
436 if ($features == 'tax') {
437 $feature2 = 'charges';
438 }
439 if ($features == 'workstation') {
440 $feature2 = 'workstation';
441 }
442 if ($features == 'fournisseur') { // When vendor invoice and purchase order are into module 'fournisseur'
443 $features = 'fournisseur';
444 if (is_object($object) && $object->element == 'invoice_supplier') {
445 $feature2 = 'facture';
446 } elseif (is_object($object) && $object->element == 'order_supplier') {
447 $feature2 = 'commande';
448 }
449 }
450 if ($features == 'payment_sc') {
451 $tableandshare = 'paiementcharge';
452 $parentfortableentity = 'fk_charge@chargesociales';
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 == 'task') {
893 $feature = 'projet_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'); // Test for task object
915 $checkhierarchy = array('expensereport', 'holiday'); // 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 if (getDolGlobalInt('MAIN_SEE_SUBORDINATES')) {
978 $userschilds = $user->getAllChildIds();
979 $sql .= " OR sc.fk_user IN (".$db->sanitize(implode(',', $userschilds)).")";
980 }
981 $sql .= ")";
982 $sql .= " AND sc.fk_soc = s.rowid";
983 $sql .= " AND s.entity IN (".getEntity($sharedelement, 1).")";
984 } elseif (isModEnabled('multicompany')) {
985 // If multicompany and internal users with all permissions, check user is in correct entity
986 $sql = "SELECT COUNT(s.rowid) as nb";
987 $sql .= " FROM ".MAIN_DB_PREFIX."societe as s";
988 $sql .= " WHERE s.rowid IN (".$db->sanitize($objectid, 1).")";
989 $sql .= " AND s.entity IN (".getEntity($sharedelement, 1).")";
990 }
991
992 $checkonentitydone = 1;
993 }
994 if (in_array($feature, $checkparentsoc) && $objectid > 0) { // Test on entity + link to thirdparty. Allowed if link is empty (Ex: contacts...).
995 // If external user: Check permission for external users
996 if ($user->socid > 0) {
997 $sql = "SELECT COUNT(dbt.".$dbt_select.") as nb";
998 $sql .= " FROM ".MAIN_DB_PREFIX.$dbtablename." as dbt";
999 $sql .= " WHERE dbt.".$dbt_select." IN (".$db->sanitize($objectid, 1).")";
1000 $sql .= " AND dbt.fk_soc = ".((int) $user->socid);
1001 } elseif (isModEnabled("societe") && ($user->hasRight('societe', 'lire') && !$user->hasRight('societe', 'client', 'voir'))) {
1002 // If internal user: Check permission for internal users that are restricted on their objects
1003 $sql = "SELECT COUNT(dbt.".$dbt_select.") as nb";
1004 $sql .= " FROM ".MAIN_DB_PREFIX.$dbtablename." as dbt";
1005 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON dbt.fk_soc = sc.fk_soc AND sc.fk_user = ".((int) $user->id);
1006 $sql .= " WHERE dbt.".$dbt_select." IN (".$db->sanitize($objectid, 1).")";
1007 $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
1008 $sql .= " AND dbt.entity IN (".getEntity($sharedelement, 1).")";
1009 } elseif (isModEnabled('multicompany')) {
1010 // If multicompany and internal users with all permissions, check user is in correct entity
1011 $sql = "SELECT COUNT(dbt.".$dbt_select.") as nb";
1012 $sql .= " FROM ".MAIN_DB_PREFIX.$dbtablename." as dbt";
1013 $sql .= " WHERE dbt.".$dbt_select." IN (".$db->sanitize($objectid, 1).")";
1014 $sql .= " AND dbt.entity IN (".getEntity($sharedelement, 1).")";
1015 }
1016
1017 $checkonentitydone = 1;
1018 }
1019 if (in_array($feature, $checkproject) && $objectid > 0) {
1020 if (isModEnabled('project') && !$user->hasRight('projet', 'all', 'lire')) {
1021 $projectid = $objectid;
1022
1023 include_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
1024 $projectstatic = new Project($db);
1025 $tmps = $projectstatic->getProjectsAuthorizedForUser($user, 0, 1, 0);
1026
1027 $tmparray = explode(',', $tmps);
1028 if (!in_array($projectid, $tmparray)) {
1029 return false;
1030 }
1031 } else {
1032 $sql = "SELECT COUNT(dbt.".$dbt_select.") as nb";
1033 $sql .= " FROM ".MAIN_DB_PREFIX.$dbtablename." as dbt";
1034 $sql .= " WHERE dbt.".$dbt_select." IN (".$db->sanitize($objectid, 1).")";
1035 $sql .= " AND dbt.entity IN (".getEntity($sharedelement, 1).")";
1036 }
1037 $checkonentitydone = 1;
1038 }
1039 if (in_array($feature, $checktask) && $objectid > 0) {
1040 if (isModEnabled('project') && !$user->hasRight('projet', 'all', 'lire')) {
1041 $task = new Task($db);
1042 $task->fetch($objectid);
1043 $projectid = $task->fk_project;
1044
1045 include_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
1046 $projectstatic = new Project($db);
1047 $tmps = $projectstatic->getProjectsAuthorizedForUser($user, 0, 1, 0);
1048
1049 $tmparray = explode(',', $tmps);
1050 if (!in_array($projectid, $tmparray)) {
1051 return false;
1052 }
1053 } else {
1054 $sql = "SELECT COUNT(dbt.".$dbt_select.") as nb";
1055 $sql .= " FROM ".MAIN_DB_PREFIX.$dbtablename." as dbt";
1056 $sql .= " WHERE dbt.".$dbt_select." IN (".$db->sanitize($objectid, 1).")";
1057 $sql .= " AND dbt.entity IN (".getEntity($sharedelement, 1).")";
1058 }
1059
1060 $checkonentitydone = 1;
1061 }
1062 //var_dump($sql);
1063
1064 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
1065 // If external user: Check permission for external users
1066 if ($user->socid > 0) {
1067 if (empty($dbt_keyfield)) {
1068 dol_print_error(null, 'Param dbt_keyfield is required but not defined');
1069 }
1070 $sql = "SELECT COUNT(dbt.".$dbt_keyfield.") as nb";
1071 $sql .= " FROM ".MAIN_DB_PREFIX.$dbtablename." as dbt";
1072 $sql .= " WHERE dbt.rowid IN (".$db->sanitize($objectid, 1).")";
1073 $sql .= " AND dbt.".$dbt_keyfield." = ".((int) $user->socid);
1074 } elseif (isModEnabled("societe") && !$user->hasRight('societe', 'client', 'voir')) {
1075 // If internal user without permission to see all thirdparties: Check permission for internal users that are restricted on their objects
1076 if ($feature != 'ticket') {
1077 if (empty($dbt_keyfield)) {
1078 dol_print_error(null, 'Param dbt_keyfield is required but not defined');
1079 }
1080 $sql = "SELECT COUNT(sc.fk_soc) as nb";
1081 $sql .= " FROM ".MAIN_DB_PREFIX.$dbtablename." as dbt";
1082 $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
1083 $sql .= " WHERE dbt.".$dbt_select." IN (".$db->sanitize($objectid, 1).")";
1084 $sql .= " AND dbt.entity IN (".getEntity($sharedelement, 1).")";
1085 $sql .= " AND sc.fk_soc = dbt.".$dbt_keyfield;
1086 $sql .= " AND (sc.fk_user = ".((int) $user->id);
1087 if (getDolGlobalInt('MAIN_SEE_SUBORDINATES')) {
1088 $userschilds = $user->getAllChildIds();
1089 foreach ($userschilds as $key => $value) {
1090 $sql .= ' OR sc.fk_user = '.((int) $value);
1091 }
1092 }
1093 $sql .= ')';
1094 } else {
1095 // On ticket, the thirdparty is not mandatory, so we need a special test to accept record with no thirdparties.
1096 $sql = "SELECT COUNT(dbt.".$dbt_select.") as nb";
1097 $sql .= " FROM ".MAIN_DB_PREFIX.$dbtablename." as dbt";
1098 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON sc.fk_soc = dbt.".$dbt_keyfield." AND sc.fk_user = ".((int) $user->id);
1099 $sql .= " WHERE dbt.".$dbt_select." IN (".$db->sanitize($objectid, 1).")";
1100 $sql .= " AND dbt.entity IN (".getEntity($sharedelement, 1).")";
1101 $sql .= " AND (sc.fk_user = ".((int) $user->id)." OR sc.fk_user IS NULL)";
1102 }
1103 } elseif (isModEnabled('multicompany')) {
1104 // If multicompany, and user is an internal user with all permissions, check that object is in correct entity
1105 $sql = "SELECT COUNT(dbt.".$dbt_select.") as nb";
1106 $sql .= " FROM ".MAIN_DB_PREFIX.$dbtablename." as dbt";
1107 $sql .= " WHERE dbt.".$dbt_select." IN (".$db->sanitize($objectid, 1).")";
1108 $sql .= " AND dbt.entity IN (".getEntity($sharedelement, 1).")";
1109 }
1110 }
1111
1112 // For events, check on users assigned to event
1113 if ($feature === 'agenda' && $objectid > 0) {
1114 // Also check owner or attendee for users without allactions->read
1115 if ($objectid > 0 && !$user->hasRight('agenda', 'allactions', 'read')) {
1116 require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php';
1117 $action = new ActionComm($db);
1118 $action->fetch($objectid);
1119 if ($action->authorid != $user->id && $action->userownerid != $user->id && !(array_key_exists($user->id, $action->userassigned))) {
1120 return false;
1121 }
1122 }
1123 }
1124
1125 // For some object, we also have to check it is in the user hierarchy
1126 // Param $object must be the full object and not a simple id to have this test possible.
1127 if (in_array($feature, $checkhierarchy) && is_object($object) && $objectid > 0) {
1128 $childids = $user->getAllChildIds(1);
1129 $useridtocheck = 0;
1130 if ($feature == 'holiday') {
1131 $useridtocheck = $object->fk_user;
1132 if (!$user->hasRight('holiday', 'readall') && !in_array($useridtocheck, $childids) && !in_array($object->fk_validator, $childids)) {
1133 return false;
1134 }
1135 }
1136 if ($feature == 'expensereport') {
1137 $useridtocheck = $object->fk_user_author;
1138 if (!$user->hasRight('expensereport', 'readall')) {
1139 if (!in_array($useridtocheck, $childids)) {
1140 return false;
1141 }
1142 }
1143 }
1144 }
1145
1146 // For some object, we also have to check it is public or owned by user
1147 // Param $object must be the full object and not a simple id to have this test possible.
1148 if (in_array($feature, $checkuser) && is_object($object) && $objectid > 0) {
1149 $useridtocheck = $object->fk_user;
1150 if (!empty($useridtocheck) && $useridtocheck > 0 && $useridtocheck != $user->id && empty($user->admin)) {
1151 return false;
1152 }
1153 }
1154
1155 if ($sql) {
1156 $resql = $db->query($sql);
1157 if ($resql) {
1158 $obj = $db->fetch_object($resql);
1159 if (!$obj || $obj->nb < count(explode(',', $objectid))) { // error if we found 0 or less record than nb of id provided
1160 return false;
1161 }
1162 } else {
1163 dol_syslog("Bad forged sql in checkUserAccessToObject", LOG_WARNING);
1164 return false;
1165 }
1166 }
1167 }
1168
1169 return true;
1170}
1171
1172
1184function httponly_accessforbidden($message = '1', $http_response_code = 403, $stringalreadysanitized = 0)
1185{
1186 top_httphead();
1187 http_response_code($http_response_code);
1188
1189 if ($stringalreadysanitized) {
1190 print $message;
1191 } else {
1192 print htmlentities($message);
1193 }
1194
1195 exit(1);
1196}
1197
1211function accessforbidden($message = '', $printheader = 1, $printfooter = 1, $showonlymessage = 0, $params = null)
1212{
1213 global $conf, $db, $user, $langs, $hookmanager;
1214 global $action, $object;
1215
1216 if (!is_object($langs)) {
1217 include_once DOL_DOCUMENT_ROOT.'/core/class/translate.class.php';
1218 $langs = new Translate('', $conf);
1219 $langs->setDefaultLang();
1220 }
1221
1222 $langs->loadLangs(array("main", "errors"));
1223
1224 if ($printheader && !defined('NOHEADERNOFOOTER')) {
1225 if (function_exists("llxHeader")) {
1226 llxHeader('');
1227 } elseif (function_exists("llxHeaderVierge")) {
1228 llxHeaderVierge('');
1229 }
1230 print '<div style="padding: 20px">';
1231 }
1232 print '<div class="error">';
1233 if (empty($message)) {
1234 print $langs->trans("ErrorForbidden");
1235 } else {
1236 print $langs->trans($message);
1237 }
1238 print '</div>';
1239 print '<br>';
1240 if (empty($showonlymessage)) {
1241 if (empty($hookmanager)) {
1242 include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php';
1243 $hookmanager = new HookManager($db);
1244 // Initialize a technical object to manage hooks of page. Note that conf->hooks_modules contains an array of hook context
1245 $hookmanager->initHooks(array('main'));
1246 }
1247
1248 $parameters = array('message' => $message, 'params' => $params);
1249 $reshook = $hookmanager->executeHooks('getAccessForbiddenMessage', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
1250 print $hookmanager->resPrint;
1251 if (empty($reshook)) {
1252 $langs->loadLangs(array("errors"));
1253 if ($user->login) {
1254 print $langs->trans("CurrentLogin").': <span class="error">'.$user->login.'</span><br>';
1255 print $langs->trans("ErrorForbidden2", $langs->transnoentitiesnoconv("Home"), $langs->transnoentitiesnoconv("Users"));
1256 print $langs->trans("ErrorForbidden4");
1257 } else {
1258 print $langs->trans("ErrorForbidden3");
1259 }
1260 }
1261 }
1262 if ($printfooter && !defined('NOHEADERNOFOOTER') && function_exists("llxFooter")) {
1263 print '</div>';
1264 llxFooter();
1265 }
1266
1267 exit(0);
1268}
1269
1270
1278{
1279 $max = getDolGlobalString('MAIN_UPLOAD_DOC'); // In Kb
1280
1281 $maxphp = @ini_get('upload_max_filesize'); // In unknown
1282 if (preg_match('/k$/i', $maxphp)) {
1283 $maxphp = preg_replace('/k$/i', '', $maxphp);
1284 $maxphp = (int) ((float) $maxphp * 1);
1285 }
1286 if (preg_match('/m$/i', $maxphp)) {
1287 $maxphp = preg_replace('/m$/i', '', $maxphp);
1288 $maxphp = (int) ((float) $maxphp * 1024);
1289 }
1290 if (preg_match('/g$/i', $maxphp)) {
1291 $maxphp = preg_replace('/g$/i', '', $maxphp);
1292 $maxphp = (int) ((float) $maxphp * 1024 * 1024);
1293 }
1294 if (preg_match('/t$/i', $maxphp)) {
1295 $maxphp = preg_replace('/t$/i', '', $maxphp);
1296 $maxphp = (int) ((float) $maxphp * 1024 * 1024 * 1024);
1297 }
1298 $maxphp2 = @ini_get('post_max_size'); // In unknown
1299 if (preg_match('/k$/i', $maxphp2)) {
1300 $maxphp2 = preg_replace('/k$/i', '', $maxphp2);
1301 $maxphp2 = (int) ((float) $maxphp2) * 1;
1302 }
1303 if (preg_match('/m$/i', $maxphp2)) {
1304 $maxphp2 = preg_replace('/m$/i', '', $maxphp2);
1305 $maxphp2 = (int) ((float) $maxphp2 * 1024);
1306 }
1307 if (preg_match('/g$/i', $maxphp2)) {
1308 $maxphp2 = preg_replace('/g$/i', '', $maxphp2);
1309 $maxphp2 = (int) ((float) $maxphp2 * 1024 * 1024);
1310 }
1311 if (preg_match('/t$/i', $maxphp2)) {
1312 $maxphp2 = preg_replace('/t$/i', '', $maxphp2);
1313 $maxphp2 = (int) ((float) $maxphp2 * 1024 * 1024 * 1024);
1314 }
1315 // Now $max and $maxphp and $maxphp2 are in Kb
1316 $maxmin = $max;
1317 $maxphptoshow = $maxphptoshowparam = '';
1318 if ($maxphp > 0) {
1319 $maxmin = min($maxmin, $maxphp);
1320 $maxphptoshow = $maxphp;
1321 $maxphptoshowparam = 'upload_max_filesize';
1322 }
1323 if ($maxphp2 > 0) {
1324 $maxmin = min($maxmin, $maxphp2);
1325 if ($maxphp2 < $maxphp) {
1326 $maxphptoshow = $maxphp2;
1327 $maxphptoshowparam = 'post_max_size';
1328 }
1329 }
1330 //var_dump($maxphp.'-'.$maxphp2);
1331 //var_dump($maxmin);
1332
1333 return array('max' => $max, 'maxmin' => $maxmin, 'maxphptoshow' => $maxphptoshow, 'maxphptoshowparam' => $maxphptoshowparam);
1334}
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($head='', $title='', $help_url='', $target='', $disablejs=0, $disablehead=0, $arrayofjs='', $arrayofcss='', $morequerystring='', $morecssonbody='', $replacemainareaby='', $disablenofollow=0, $disablenoindex=0)
Empty header.
Definition wrapper.php:70
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.
llxFooter()
Footer empty.
Definition document.php:107
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 a 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.