dolibarr  9.0.0
security.lib.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (C) 2008-2011 Laurent Destailleur <eldy@users.sourceforge.net>
3  * Copyright (C) 2008-2017 Regis Houssin <regis.houssin@inodbox.com>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  * or see http://www.gnu.org/
18  */
19 
37 function dol_encode($chain, $key='1')
38 {
39  if (is_numeric($key) && $key == '1') // rule 1 is offset of 17 for char
40  {
41  $output_tab=array();
42  $strlength=dol_strlen($chain);
43  for ($i=0; $i < $strlength; $i++)
44  {
45  $output_tab[$i] = chr(ord(substr($chain,$i,1))+17);
46  }
47  $chain = implode("",$output_tab);
48  }
49  elseif ($key)
50  {
51  $result='';
52  $strlength=dol_strlen($chain);
53  for ($i=0; $i < $strlength; $i++)
54  {
55  $keychar = substr($key, ($i % strlen($key))-1, 1);
56  $result.= chr(ord(substr($chain,$i,1))+(ord($keychar)-65));
57  }
58  $chain=$result;
59  }
60 
61  return base64_encode($chain);
62 }
63 
73 function dol_decode($chain, $key='1')
74 {
75  $chain = base64_decode($chain);
76 
77  if (is_numeric($key) && $key == '1') // rule 1 is offset of 17 for char
78  {
79  $output_tab=array();
80  $strlength=dol_strlen($chain);
81  for ($i=0; $i < $strlength;$i++)
82  {
83  $output_tab[$i] = chr(ord(substr($chain,$i,1))-17);
84  }
85 
86  $chain = implode("",$output_tab);
87  }
88  elseif ($key)
89  {
90  $result='';
91  $strlength=dol_strlen($chain);
92  for ($i=0; $i < $strlength; $i++)
93  {
94  $keychar = substr($key, ($i % strlen($key))-1, 1);
95  $result.= chr(ord(substr($chain, $i, 1))-(ord($keychar)-65));
96  }
97  $chain=$result;
98  }
99 
100  return $chain;
101 }
102 
103 
114 function dol_hash($chain, $type='0')
115 {
116  global $conf;
117 
118  // No need to add salt for password_hash
119  if (($type == '0' || $type == 'auto') && ! empty($conf->global->MAIN_SECURITY_HASH_ALGO) && $conf->global->MAIN_SECURITY_HASH_ALGO == 'password_hash' && function_exists('password_hash'))
120  {
121  return password_hash($chain, PASSWORD_DEFAULT);
122  }
123 
124  // Salt value
125  if (! empty($conf->global->MAIN_SECURITY_SALT)) $chain=$conf->global->MAIN_SECURITY_SALT.$chain;
126 
127  if ($type == '1' || $type == 'sha1') return sha1($chain);
128  else if ($type == '2' || $type == 'sha1md5') return sha1(md5($chain));
129  else if ($type == '3' || $type == 'md5') return md5($chain);
130  else if ($type == '4' || $type == 'md5openldap') return '{md5}'.base64_encode(mhash(MHASH_MD5,$chain)); // For OpenLdap with md5 (based on an unencrypted password in base)
131  else if ($type == '5') return hash('sha256',$chain);
132  else if (! empty($conf->global->MAIN_SECURITY_HASH_ALGO) && $conf->global->MAIN_SECURITY_HASH_ALGO == 'sha1') return sha1($chain);
133  else if (! empty($conf->global->MAIN_SECURITY_HASH_ALGO) && $conf->global->MAIN_SECURITY_HASH_ALGO == 'sha1md5') return sha1(md5($chain));
134 
135  // No particular encoding defined, use default
136  return md5($chain);
137 }
138 
150 function dol_verifyHash($chain, $hash, $type='0')
151 {
152  global $conf;
153 
154  if ($type == '0' && ! empty($conf->global->MAIN_SECURITY_HASH_ALGO) && $conf->global->MAIN_SECURITY_HASH_ALGO == 'password_hash' && function_exists('password_verify')) {
155  if ($hash[0] == '$') return password_verify($chain, $hash);
156  else if(strlen($hash) == 32) return dol_verifyHash($chain, $hash, '3'); // md5
157  else if(strlen($hash) == 40) return dol_verifyHash($chain, $hash, '2'); // sha1md5
158 
159  return false;
160  }
161 
162  return dol_hash($chain, $type) == $hash;
163 }
164 
165 
181 function restrictedArea($user, $features, $objectid=0, $tableandshare='', $feature2='', $dbt_keyfield='fk_soc', $dbt_select='rowid', $isdraft=0)
182 {
183  global $db, $conf;
184  global $hookmanager;
185 
186  //dol_syslog("functions.lib:restrictedArea $feature, $objectid, $dbtablename,$feature2,$dbt_socfield,$dbt_select");
187  //print "user_id=".$user->id.", features=".$features.", feature2=".$feature2.", objectid=".$objectid;
188  //print ", dbtablename=".$dbtablename.", dbt_socfield=".$dbt_keyfield.", dbt_select=".$dbt_select;
189  //print ", perm: ".$features."->".$feature2."=".($user->rights->$features->$feature2->lire)."<br>";
190 
191  // Get more permissions checks from hooks
192  $parameters=array('features'=>$features, 'objectid'=>$objectid, 'idtype'=>$dbt_select);
193  $reshook=$hookmanager->executeHooks('restrictedArea',$parameters);
194  if (! empty($hookmanager->resArray['result'])) return true;
195  if ($reshook > 0) return false;
196 
197  if ($dbt_select != 'rowid' && $dbt_select != 'id') $objectid = "'".$objectid."'";
198 
199  // Features/modules to check
200  $featuresarray = array($features);
201  if (preg_match('/&/', $features)) $featuresarray = explode("&", $features);
202  else if (preg_match('/\|/', $features)) $featuresarray = explode("|", $features);
203 
204  // More subfeatures to check
205  if (! empty($feature2)) $feature2 = explode("|", $feature2);
206 
207  // More parameters
208  $params = explode('&', $tableandshare);
209  $dbtablename=(! empty($params[0]) ? $params[0] : '');
210  $sharedelement=(! empty($params[1]) ? $params[1] : $dbtablename);
211 
212  $listofmodules=explode(',',$conf->global->MAIN_MODULES_FOR_EXTERNAL);
213 
214  // Check read permission from module
215  $readok=1; $nbko=0;
216  foreach ($featuresarray as $feature) // first we check nb of test ko
217  {
218  $featureforlistofmodule=$feature;
219  if ($featureforlistofmodule == 'produit') $featureforlistofmodule='product';
220  if (! empty($user->societe_id) && ! empty($conf->global->MAIN_MODULES_FOR_EXTERNAL) && ! in_array($featureforlistofmodule,$listofmodules)) // If limits on modules for external users, module must be into list of modules for external users
221  {
222  $readok=0; $nbko++;
223  continue;
224  }
225 
226  if ($feature == 'societe')
227  {
228  if (! $user->rights->societe->lire && ! $user->rights->fournisseur->lire) { $readok=0; $nbko++; }
229  }
230  else if ($feature == 'contact')
231  {
232  if (! $user->rights->societe->contact->lire) { $readok=0; $nbko++; }
233  }
234  else if ($feature == 'produit|service')
235  {
236  if (! $user->rights->produit->lire && ! $user->rights->service->lire) { $readok=0; $nbko++; }
237  }
238  else if ($feature == 'prelevement')
239  {
240  if (! $user->rights->prelevement->bons->lire) { $readok=0; $nbko++; }
241  }
242  else if ($feature == 'cheque')
243  {
244  if (! $user->rights->banque->cheque) { $readok=0; $nbko++; }
245  }
246  else if ($feature == 'projet')
247  {
248  if (! $user->rights->projet->lire && ! $user->rights->projet->all->lire) { $readok=0; $nbko++; }
249  }
250  else if (! empty($feature2)) // This should be used for future changes
251  {
252  $tmpreadok=1;
253  foreach($feature2 as $subfeature)
254  {
255  if (! empty($subfeature) && empty($user->rights->$feature->$subfeature->lire) && empty($user->rights->$feature->$subfeature->read)) { $tmpreadok=0; }
256  else if (empty($subfeature) && empty($user->rights->$feature->lire) && empty($user->rights->$feature->read)) { $tmpreadok=0; }
257  else { $tmpreadok=1; break; } // Break is to bypass second test if the first is ok
258  }
259  if (! $tmpreadok) // We found a test on feature that is ko
260  {
261  $readok=0; // All tests are ko (we manage here the and, the or will be managed later using $nbko).
262  $nbko++;
263  }
264  }
265  else if (! empty($feature) && ($feature!='user' && $feature!='usergroup')) // This is for old permissions
266  {
267  if (empty($user->rights->$feature->lire)
268  && empty($user->rights->$feature->read)
269  && empty($user->rights->$feature->run)) { $readok=0; $nbko++; }
270  }
271  }
272 
273  // If a or and at least one ok
274  if (preg_match('/\|/', $features) && $nbko < count($featuresarray)) $readok=1;
275 
276  if (! $readok) accessforbidden();
277  //print "Read access is ok";
278 
279  // Check write permission from module (we need to know write permission to create but also to delete drafts record)
280  $createok=1; $nbko=0;
281  if (GETPOST('action','aZ09') == 'create' || ((GETPOST("action","aZ09") == 'confirm_delete' && GETPOST("confirm","aZ09") == 'yes') || GETPOST("action","aZ09") == 'delete'))
282  {
283  foreach ($featuresarray as $feature)
284  {
285  if ($feature == 'contact')
286  {
287  if (! $user->rights->societe->contact->creer) { $createok=0; $nbko++; }
288  }
289  else if ($feature == 'produit|service')
290  {
291  if (! $user->rights->produit->creer && ! $user->rights->service->creer) { $createok=0; $nbko++; }
292  }
293  else if ($feature == 'prelevement')
294  {
295  if (! $user->rights->prelevement->bons->creer) { $createok=0; $nbko++; }
296  }
297  else if ($feature == 'commande_fournisseur')
298  {
299  if (! $user->rights->fournisseur->commande->creer) { $createok=0; $nbko++; }
300  }
301  else if ($feature == 'banque')
302  {
303  if (! $user->rights->banque->modifier) { $createok=0; $nbko++; }
304  }
305  else if ($feature == 'cheque')
306  {
307  if (! $user->rights->banque->cheque) { $createok=0; $nbko++; }
308  }
309  else if (! empty($feature2)) // This should be used
310  {
311  foreach($feature2 as $subfeature)
312  {
313  if (empty($user->rights->$feature->$subfeature->creer)
314  && empty($user->rights->$feature->$subfeature->write)
315  && empty($user->rights->$feature->$subfeature->create)) { $createok=0; $nbko++; }
316  else { $createok=1; break; } // Break to bypass second test if the first is ok
317  }
318  }
319  else if (! empty($feature)) // This is for old permissions ('creer' or 'write')
320  {
321  //print '<br>feature='.$feature.' creer='.$user->rights->$feature->creer.' write='.$user->rights->$feature->write;
322  if (empty($user->rights->$feature->creer)
323  && empty($user->rights->$feature->write)
324  && empty($user->rights->$feature->create)) { $createok=0; $nbko++; }
325  }
326  }
327 
328  // If a or and at least one ok
329  if (preg_match('/\|/', $features) && $nbko < count($featuresarray)) $createok=1;
330 
331  if (GETPOST('action','aZ09') == 'create' && ! $createok) accessforbidden();
332  //print "Write access is ok";
333  }
334 
335  // Check create user permission
336  $createuserok=1;
337  if (GETPOST('action','aZ09') == 'confirm_create_user' && GETPOST("confirm",'aZ09') == 'yes')
338  {
339  if (! $user->rights->user->user->creer) $createuserok=0;
340 
341  if (! $createuserok) accessforbidden();
342  //print "Create user access is ok";
343  }
344 
345  // Check delete permission from module
346  $deleteok=1; $nbko=0;
347  if ((GETPOST("action","aZ09") == 'confirm_delete' && GETPOST("confirm","aZ09") == 'yes') || GETPOST("action","aZ09") == 'delete')
348  {
349  foreach ($featuresarray as $feature)
350  {
351  if ($feature == 'contact')
352  {
353  if (! $user->rights->societe->contact->supprimer) $deleteok=0;
354  }
355  else if ($feature == 'produit|service')
356  {
357  if (! $user->rights->produit->supprimer && ! $user->rights->service->supprimer) $deleteok=0;
358  }
359  else if ($feature == 'commande_fournisseur')
360  {
361  if (! $user->rights->fournisseur->commande->supprimer) $deleteok=0;
362  }
363  else if ($feature == 'banque')
364  {
365  if (! $user->rights->banque->modifier) $deleteok=0;
366  }
367  else if ($feature == 'cheque')
368  {
369  if (! $user->rights->banque->cheque) $deleteok=0;
370  }
371  else if ($feature == 'ecm')
372  {
373  if (! $user->rights->ecm->upload) $deleteok=0;
374  }
375  else if ($feature == 'ftp')
376  {
377  if (! $user->rights->ftp->write) $deleteok=0;
378  }else if ($feature == 'salaries')
379  {
380  if (! $user->rights->salaries->delete) $deleteok=0;
381  }
382  else if ($feature == 'salaries')
383  {
384  if (! $user->rights->salaries->delete) $deleteok=0;
385  }
386  else if (! empty($feature2)) // This should be used for permissions on 2 levels
387  {
388  foreach($feature2 as $subfeature)
389  {
390  if (empty($user->rights->$feature->$subfeature->supprimer) && empty($user->rights->$feature->$subfeature->delete)) $deleteok=0;
391  else { $deleteok=1; break; } // For bypass the second test if the first is ok
392  }
393  }
394  else if (! empty($feature)) // This is used for permissions on 1 level
395  {
396  //print '<br>feature='.$feature.' creer='.$user->rights->$feature->supprimer.' write='.$user->rights->$feature->delete;
397  if (empty($user->rights->$feature->supprimer)
398  && empty($user->rights->$feature->delete)
399  && empty($user->rights->$feature->run)) $deleteok=0;
400  }
401  }
402 
403  // If a or and at least one ok
404  if (preg_match('/\|/', $features) && $nbko < count($featuresarray)) $deleteok=1;
405 
406  if (! $deleteok && ! ($isdraft && $createok)) accessforbidden();
407  //print "Delete access is ok";
408  }
409 
410  // If we have a particular object to check permissions on, we check this object
411  // is linked to a company allowed to $user.
412  if (! empty($objectid) && $objectid > 0)
413  {
414  $ok = checkUserAccessToObject($user, $featuresarray, $objectid, $tableandshare, $feature2, $dbt_keyfield, $dbt_select);
415  return $ok ? 1 : accessforbidden();
416  }
417 
418  return 1;
419 }
420 
435 function checkUserAccessToObject($user, $featuresarray, $objectid=0, $tableandshare='', $feature2='', $dbt_keyfield='', $dbt_select='rowid')
436 {
437  global $db, $conf;
438 
439  // More parameters
440  $params = explode('&', $tableandshare);
441  $dbtablename=(! empty($params[0]) ? $params[0] : '');
442  $sharedelement=(! empty($params[1]) ? $params[1] : $dbtablename);
443 
444  foreach ($featuresarray as $feature)
445  {
446  $sql='';
447 
448  // For backward compatibility
449  if ($feature == 'member') $feature='adherent';
450  if ($feature == 'project') $feature='projet';
451  if ($feature == 'task') $feature='projet_task';
452 
453  $check = array('adherent','banque','don','user','usergroup','product','produit','service','produit|service','categorie','resource'); // Test on entity only (Objects with no link to company)
454  $checksoc = array('societe'); // Test for societe object
455  $checkother = array('contact','agenda'); // Test on entity and link to third party. Allowed if link is empty (Ex: contacts...).
456  $checkproject = array('projet','project'); // Test for project object
457  $checktask = array('projet_task');
458  $nocheck = array('barcode','stock'); // No test
459  $checkdefault = 'all other not already defined'; // Test on entity and link to third party. Not allowed if link is empty (Ex: invoice, orders...).
460 
461  // If dbtablename not defined, we use same name for table than module name
462  if (empty($dbtablename))
463  {
464  $dbtablename = $feature;
465  $sharedelement = (! empty($params[1]) ? $params[1] : $dbtablename); // We change dbtablename, so we set sharedelement too.
466  }
467 
468  // Check permission for object with entity
469  if (in_array($feature,$check))
470  {
471  $sql = "SELECT COUNT(dbt.".$dbt_select.") as nb";
472  $sql.= " FROM ".MAIN_DB_PREFIX.$dbtablename." as dbt";
473  if (($feature == 'user' || $feature == 'usergroup') && ! empty($conf->multicompany->enabled))
474  {
475  if (! empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE))
476  {
477  if ($conf->entity == 1 && $user->admin && ! $user->entity)
478  {
479  $sql.= " WHERE dbt.".$dbt_select." IN (".$objectid.")";
480  $sql.= " AND dbt.entity IS NOT NULL";
481  }
482  else
483  {
484  $sql.= ",".MAIN_DB_PREFIX."usergroup_user as ug";
485  $sql.= " WHERE dbt.".$dbt_select." IN (".$objectid.")";
486  $sql.= " AND ((ug.fk_user = dbt.rowid";
487  $sql.= " AND ug.entity IN (".getEntity('usergroup')."))";
488  $sql.= " OR dbt.entity = 0)"; // Show always superadmin
489  }
490  }
491  else {
492  $sql.= " WHERE dbt.".$dbt_select." IN (".$objectid.")";
493  $sql.= " AND dbt.entity IN (".getEntity($sharedelement, 1).")";
494  }
495  }
496  else
497  {
498  $sql.= " WHERE dbt.".$dbt_select." IN (".$objectid.")";
499  $sql.= " AND dbt.entity IN (".getEntity($sharedelement, 1).")";
500  }
501  }
502  else if (in_array($feature,$checksoc)) // We check feature = checksoc
503  {
504  // If external user: Check permission for external users
505  if ($user->socid > 0)
506  {
507  if ($user->socid <> $objectid) return false;
508  }
509  // If internal user: Check permission for internal users that are restricted on their objects
510  else if (! empty($conf->societe->enabled) && ($user->rights->societe->lire && ! $user->rights->societe->client->voir))
511  {
512  $sql = "SELECT COUNT(sc.fk_soc) as nb";
513  $sql.= " FROM (".MAIN_DB_PREFIX."societe_commerciaux as sc";
514  $sql.= ", ".MAIN_DB_PREFIX."societe as s)";
515  $sql.= " WHERE sc.fk_soc IN (".$objectid.")";
516  $sql.= " AND sc.fk_user = ".$user->id;
517  $sql.= " AND sc.fk_soc = s.rowid";
518  $sql.= " AND s.entity IN (".getEntity($sharedelement, 1).")";
519  }
520  // If multicompany and internal users with all permissions, check user is in correct entity
521  else if (! empty($conf->multicompany->enabled))
522  {
523  $sql = "SELECT COUNT(s.rowid) as nb";
524  $sql.= " FROM ".MAIN_DB_PREFIX."societe as s";
525  $sql.= " WHERE s.rowid IN (".$objectid.")";
526  $sql.= " AND s.entity IN (".getEntity($sharedelement, 1).")";
527  }
528  }
529  else if (in_array($feature,$checkother)) // Test on entity and link to societe. Allowed if link is empty (Ex: contacts...).
530  {
531  // If external user: Check permission for external users
532  if ($user->socid > 0)
533  {
534  $sql = "SELECT COUNT(dbt.".$dbt_select.") as nb";
535  $sql.= " FROM ".MAIN_DB_PREFIX.$dbtablename." as dbt";
536  $sql.= " WHERE dbt.".$dbt_select." IN (".$objectid.")";
537  $sql.= " AND dbt.fk_soc = ".$user->socid;
538  }
539  // If internal user: Check permission for internal users that are restricted on their objects
540  else if (! empty($conf->societe->enabled) && ($user->rights->societe->lire && ! $user->rights->societe->client->voir))
541  {
542  $sql = "SELECT COUNT(dbt.".$dbt_select.") as nb";
543  $sql.= " FROM ".MAIN_DB_PREFIX.$dbtablename." as dbt";
544  $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON dbt.fk_soc = sc.fk_soc AND sc.fk_user = '".$user->id."'";
545  $sql.= " WHERE dbt.".$dbt_select." IN (".$objectid.")";
546  $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
547  $sql.= " AND dbt.entity IN (".getEntity($sharedelement, 1).")";
548  }
549  // If multicompany and internal users with all permissions, check user is in correct entity
550  else if (! empty($conf->multicompany->enabled))
551  {
552  $sql = "SELECT COUNT(dbt.".$dbt_select.") as nb";
553  $sql.= " FROM ".MAIN_DB_PREFIX.$dbtablename." as dbt";
554  $sql.= " WHERE dbt.".$dbt_select." IN (".$objectid.")";
555  $sql.= " AND dbt.entity IN (".getEntity($sharedelement, 1).")";
556  }
557  }
558  else if (in_array($feature,$checkproject))
559  {
560  if (! empty($conf->projet->enabled) && empty($user->rights->projet->all->lire))
561  {
562  include_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
563  $projectstatic=new Project($db);
564  $tmps=$projectstatic->getProjectsAuthorizedForUser($user,0,1,0);
565  $tmparray=explode(',',$tmps);
566  if (! in_array($objectid,$tmparray)) return false;
567  }
568  else
569  {
570  $sql = "SELECT COUNT(dbt.".$dbt_select.") as nb";
571  $sql.= " FROM ".MAIN_DB_PREFIX.$dbtablename." as dbt";
572  $sql.= " WHERE dbt.".$dbt_select." IN (".$objectid.")";
573  $sql.= " AND dbt.entity IN (".getEntity($sharedelement, 1).")";
574  }
575  }
576  else if (in_array($feature,$checktask))
577  {
578  if (! empty($conf->projet->enabled) && empty($user->rights->projet->all->lire))
579  {
580  $task = new Task($db);
581  $task->fetch($objectid);
582 
583  include_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
584  $projectstatic=new Project($db);
585  $tmps=$projectstatic->getProjectsAuthorizedForUser($user,0,1,0);
586  $tmparray=explode(',',$tmps);
587  if (! in_array($task->fk_project,$tmparray)) return false;
588  }
589  else
590  {
591  $sql = "SELECT COUNT(dbt.".$dbt_select.") as nb";
592  $sql.= " FROM ".MAIN_DB_PREFIX.$dbtablename." as dbt";
593  $sql.= " WHERE dbt.".$dbt_select." IN (".$objectid.")";
594  $sql.= " AND dbt.entity IN (".getEntity($sharedelement, 1).")";
595  }
596  }
597  else if (! in_array($feature,$nocheck)) // By default (case of $checkdefault), we check on object entity + link to third party on field $dbt_keyfield
598  {
599  // If external user: Check permission for external users
600  if ($user->socid > 0)
601  {
602  if (empty($dbt_keyfield)) dol_print_error('','Param dbt_keyfield is required but not defined');
603  $sql = "SELECT COUNT(dbt.".$dbt_keyfield.") as nb";
604  $sql.= " FROM ".MAIN_DB_PREFIX.$dbtablename." as dbt";
605  $sql.= " WHERE dbt.rowid IN (".$objectid.")";
606  $sql.= " AND dbt.".$dbt_keyfield." = ".$user->socid;
607  }
608  // If internal user: Check permission for internal users that are restricted on their objects
609  else if (! empty($conf->societe->enabled) && ($user->rights->societe->lire && ! $user->rights->societe->client->voir))
610  {
611  if (empty($dbt_keyfield)) dol_print_error('','Param dbt_keyfield is required but not defined');
612  $sql = "SELECT COUNT(sc.fk_soc) as nb";
613  $sql.= " FROM ".MAIN_DB_PREFIX.$dbtablename." as dbt";
614  $sql.= ", ".MAIN_DB_PREFIX."societe as s";
615  $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
616  $sql.= " WHERE dbt.".$dbt_select." IN (".$objectid.")";
617  $sql.= " AND sc.fk_soc = dbt.".$dbt_keyfield;
618  $sql.= " AND dbt.".$dbt_keyfield." = s.rowid";
619  $sql.= " AND dbt.entity IN (".getEntity($sharedelement, 1).")";
620  $sql.= " AND sc.fk_user = ".$user->id;
621  }
622  // If multicompany and internal users with all permissions, check user is in correct entity
623  else if (! empty($conf->multicompany->enabled))
624  {
625  $sql = "SELECT COUNT(dbt.".$dbt_select.") as nb";
626  $sql.= " FROM ".MAIN_DB_PREFIX.$dbtablename." as dbt";
627  $sql.= " WHERE dbt.".$dbt_select." IN (".$objectid.")";
628  $sql.= " AND dbt.entity IN (".getEntity($sharedelement, 1).")";
629  }
630  }
631 
632  if ($sql)
633  {
634  $resql=$db->query($sql);
635  if ($resql)
636  {
637  $obj = $db->fetch_object($resql);
638  if (! $obj || $obj->nb < count(explode(',', $objectid))) return false;
639  }
640  else
641  {
642  return false;
643  }
644  }
645  }
646  return true;
647 }
648 
659 function accessforbidden($message='',$printheader=1,$printfooter=1,$showonlymessage=0)
660 {
661  global $conf, $db, $user, $langs;
662  if (! is_object($langs))
663  {
664  include_once DOL_DOCUMENT_ROOT.'/core/class/translate.class.php';
665  $langs=new Translate('',$conf);
666  $langs->setDefaultLang();
667  }
668 
669  $langs->load("errors");
670 
671  if ($printheader)
672  {
673  if (function_exists("llxHeader")) llxHeader('');
674  else if (function_exists("llxHeaderVierge")) llxHeaderVierge('');
675  }
676  print '<div class="error">';
677  if (! $message) print $langs->trans("ErrorForbidden");
678  else print $message;
679  print '</div>';
680  print '<br>';
681  if (empty($showonlymessage))
682  {
683  if ($user->login)
684  {
685  print $langs->trans("CurrentLogin").': <font class="error">'.$user->login.'</font><br>';
686  print $langs->trans("ErrorForbidden2",$langs->trans("Home"),$langs->trans("Users"));
687  }
688  else
689  {
690  print $langs->trans("ErrorForbidden3");
691  }
692  }
693  if ($printfooter && function_exists("llxFooter")) llxFooter();
694  exit(0);
695 }
llxFooter()
Empty footer.
Definition: wrapper.php:56
GETPOST($paramname, $check='none', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
print
Draft customers invoices.
Definition: index.php:91
if(! empty($conf->facture->enabled) && $user->rights->facture->lire) if(! empty($conf->fournisseur->enabled) && $user->rights->fournisseur->facture->lire) if(! empty($conf->don->enabled) && $user->rights->societe->lire) if(! empty($conf->tax->enabled) && $user->rights->tax->charges->lire) if(! empty($conf->facture->enabled) &&! empty($conf->commande->enabled) && $user->rights->commande->lire &&empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) if(! empty($conf->facture->enabled) && $user->rights->facture->lire) if(! empty($conf->fournisseur->enabled) && $user->rights->fournisseur->facture->lire) $resql
Social contributions to pay.
Definition: index.php:1053
checkUserAccessToObject($user, $featuresarray, $objectid=0, $tableandshare='', $feature2='', $dbt_keyfield='', $dbt_select='rowid')
Check access by user to object.
dol_print_error($db='', $error='', $errors=null)
Affiche message erreur system avec toutes les informations pour faciliter le diagnostic et la remonte...
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0)
Show a message to say access is forbidden and stop program Calling this function terminate execution ...
Class to manage projects.
dol_encode($chain, $key='1')
Encode a string with base 64 algorithm + specific delta change.
llxHeader()
Empty header.
Definition: wrapper.php:44
Class to manage translations.
dol_decode($chain, $key='1')
Decode a base 64 encoded + specific delta change.
llxHeaderVierge()
Header function.
Class to manage tasks.
Definition: task.class.php:33
dol_verifyHash($chain, $hash, $type='0')
Compute a hash and compare it to the given one For backward compatibility reasons, if the hash is not in the password_hash format, we will try to match against md5 and sha1md5 If constant MAIN_SECURITY_HASH_ALGO is defined, we use this function as hashing function.
restrictedArea($user, $features, $objectid=0, $tableandshare='', $feature2='', $dbt_keyfield='fk_soc', $dbt_select='rowid', $isdraft=0)
Check permissions of a user to show a page and an object.
dol_hash($chain, $type='0')
Returns a hash of a string.
dol_strlen($string, $stringencoding='UTF-8')
Make a strlen call.