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