dolibarr  7.0.0-beta
security.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (C) 2004-2009 Laurent Destailleur <eldy@users.sourceforge.net>
3  * Copyright (C) 2005-2007 Regis Houssin <regis.houssin@capnetworks.com>
4  * Copyright (C) 2013-2015 Juanjo Menent <jmenent@2byte.es>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program. If not, see <http://www.gnu.org/licenses/>.
18  */
19 
26 require '../main.inc.php';
27 require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
28 require_once DOL_DOCUMENT_ROOT.'/core/lib/security2.lib.php';
29 
30 $action=GETPOST('action','aZ09');
31 
32 $langs->load("users");
33 $langs->load("admin");
34 $langs->load("other");
35 
36 if (!$user->admin) accessforbidden();
37 
38 // Allow/Disallow change to clear passwords once passwords are crypted
39 $allow_disable_encryption=true;
40 
41 /*
42  * Actions
43  */
44 if ($action == 'setgeneraterule')
45 {
46  if (! dolibarr_set_const($db, 'USER_PASSWORD_GENERATED',$_GET["value"],'chaine',0,'',$conf->entity))
47  {
48  dol_print_error($db);
49  }
50  else
51  {
52  header("Location: ".$_SERVER["PHP_SELF"]);
53  exit;
54  }
55 }
56 
57 if ($action == 'activate_encrypt')
58 {
59  $error=0;
60 
61  $db->begin();
62 
63  dolibarr_set_const($db, "DATABASE_PWD_ENCRYPTED", "1",'chaine',0,'',$conf->entity);
64 
65  $sql = "SELECT u.rowid, u.pass, u.pass_crypted";
66  $sql.= " FROM ".MAIN_DB_PREFIX."user as u";
67  $sql.= " WHERE u.pass IS NOT NULL AND LENGTH(u.pass) < 32"; // Not a MD5 value
68 
69  $resql=$db->query($sql);
70  if ($resql)
71  {
72  $numrows=$db->num_rows($resql);
73  $i=0;
74  while ($i < $numrows)
75  {
76  $obj=$db->fetch_object($resql);
77  if (dol_hash($obj->pass))
78  {
79  $sql = "UPDATE ".MAIN_DB_PREFIX."user";
80  $sql.= " SET pass_crypted = '".dol_hash($obj->pass)."', pass = NULL";
81  $sql.= " WHERE rowid=".$obj->rowid;
82  //print $sql;
83 
84  $resql2 = $db->query($sql);
85  if (! $resql2)
86  {
87  dol_print_error($db);
88  $error++;
89  break;
90  }
91 
92  $i++;
93  }
94  }
95  }
96  else dol_print_error($db);
97 
98  //print $error." ".$sql;
99  //exit;
100  if (! $error)
101  {
102  $db->commit();
103  header("Location: security.php");
104  exit;
105  }
106  else
107  {
108  $db->rollback();
109  dol_print_error($db,'');
110  }
111 }
112 else if ($action == 'disable_encrypt')
113 {
114  //On n'autorise pas l'annulation de l'encryption car les mots de passe ne peuvent pas etre decodes
115  //Do not allow "disable encryption" as passwords cannot be decrypted
116  if ($allow_disable_encryption)
117  {
118  dolibarr_del_const($db, "DATABASE_PWD_ENCRYPTED",$conf->entity);
119  }
120  header("Location: security.php");
121  exit;
122 }
123 
124 if ($action == 'activate_encryptdbpassconf')
125 {
126  $result = encodedecode_dbpassconf(1);
127  if ($result > 0)
128  {
129  sleep(3); // Don't know why but we need to wait file is completely saved before making the reload. Even with flush and clearstatcache, we need to wait.
130 
131  // database value not required
132  //dolibarr_set_const($db, "MAIN_DATABASE_PWD_CONFIG_ENCRYPTED", "1");
133  header("Location: security.php");
134  exit;
135  }
136  else
137  {
138  setEventMessages($langs->trans('InstrucToEncodePass',dol_encode($dolibarr_main_db_pass)), null, 'warnings');
139  }
140 }
141 else if ($action == 'disable_encryptdbpassconf')
142 {
143  $result = encodedecode_dbpassconf(0);
144  if ($result > 0)
145  {
146  sleep(3); // Don't know why but we need to wait file is completely saved before making the reload. Even with flush and clearstatcache, we need to wait.
147 
148  // database value not required
149  //dolibarr_del_const($db, "MAIN_DATABASE_PWD_CONFIG_ENCRYPTED",$conf->entity);
150  header("Location: security.php");
151  exit;
152  }
153  else
154  {
155  setEventMessages($langs->trans('InstrucToClearPass',$dolibarr_main_db_pass), null, 'warnings');
156  }
157 }
158 
159 if ($action == 'activate_MAIN_SECURITY_DISABLEFORGETPASSLINK')
160 {
161  dolibarr_set_const($db, "MAIN_SECURITY_DISABLEFORGETPASSLINK", '1','chaine',0,'',$conf->entity);
162  header("Location: security.php");
163  exit;
164 }
165 else if ($action == 'disable_MAIN_SECURITY_DISABLEFORGETPASSLINK')
166 {
167  dolibarr_del_const($db, "MAIN_SECURITY_DISABLEFORGETPASSLINK",$conf->entity);
168  header("Location: security.php");
169  exit;
170 }
171 
172 if ($action == 'maj_pattern')
173 {
174  dolibarr_set_const($db, "USER_PASSWORD_PATTERN", GETPOST("pattern"),'chaine',0,'',$conf->entity);
175  header("Location: security.php");
176  exit;
177 }
178 
179 
180 
181 
182 
183 
184 
185 /*
186  * View
187  */
188 $form = new Form($db);
189 
190 $wikihelp='EN:Setup_Security|FR:Paramétrage_Sécurité|ES:Configuración_Seguridad';
191 llxHeader('',$langs->trans("Passwords"),$wikihelp);
192 
193 print load_fiche_titre($langs->trans("SecuritySetup"),'','title_setup');
194 
195 print $langs->trans("GeneratedPasswordDesc")."<br>\n";
196 print "<br>\n";
197 
198 
199 $head=security_prepare_head();
200 
201 dol_fiche_head($head, 'passwords', $langs->trans("Security"), -1);
202 
203 
204 $var=false;
205 
206 
207 // Choix du gestionnaire du generateur de mot de passe
208 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
209 print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
210 print '<input type="hidden" name="action" value="update">';
211 print '<input type="hidden" name="constname" value="USER_PASSWORD_GENERATED">';
212 print '<input type="hidden" name="consttype" value="yesno">';
213 
214 // Charge tableau des modules generation
215 $dir = "../core/modules/security/generate";
216 clearstatcache();
217 $handle=opendir($dir);
218 $i=1;
219 if (is_resource($handle))
220 {
221  while (($file = readdir($handle))!==false)
222  {
223  if (preg_match('/(modGeneratePass[a-z]+)\.class\.php/i',$file,$reg))
224  {
225  // Charging the numbering class
226  $classname = $reg[1];
227  require_once $dir.'/'.$file;
228 
229  $obj = new $classname($db,$conf,$langs,$user);
230  $arrayhandler[$obj->id]=$obj;
231  $i++;
232  }
233  }
234  closedir($handle);
235 }
236 
237 print '<table class="noborder" width="100%">';
238 print '<tr class="liste_titre">';
239 print '<td colspan="2">'.$langs->trans("RuleForGeneratedPasswords").'</td>';
240 print '<td>'.$langs->trans("Example").'</td>';
241 print '<td align="center">'.$langs->trans("Activated").'</td>';
242 print '</tr>';
243 
244 foreach ($arrayhandler as $key => $module)
245 {
246  // Show modules according to features level
247  if ($module->version == 'development' && $conf->global->MAIN_FEATURES_LEVEL < 2) continue;
248  if ($module->version == 'experimental' && $conf->global->MAIN_FEATURES_LEVEL < 1) continue;
249 
250  if ($module->isEnabled())
251  {
252  $var = !$var;
253  print '<tr class="oddeven"><td width="100">';
254  print ucfirst($key);
255  print "</td><td>\n";
256  print $module->getDescription().'<br>';
257  print $langs->trans("MinLength").': '.$module->length;
258  print '</td>';
259 
260  // Show example of numbering module
261  print '<td class="nowrap">';
262  $tmp=$module->getExample();
263  if (preg_match('/^Error/',$tmp)) { $langs->load("errors"); print '<div class="error">'.$langs->trans($tmp).'</div>'; }
264  elseif ($tmp=='NotConfigured') print $langs->trans($tmp);
265  else print $tmp;
266  print '</td>'."\n";
267 
268  print '<td width="100" align="center">';
269  if ($conf->global->USER_PASSWORD_GENERATED == $key)
270  {
271  print img_picto('','tick');
272  }
273  else
274  {
275  print '<a href="'.$_SERVER['PHP_SELF'].'?action=setgeneraterule&amp;value='.$key.'">'.$langs->trans("Activate").'</a>';
276  }
277  print "</td></tr>\n";
278  }
279 }
280 print '</table>';
281 print '</form>';
282 
283 //if($conf->global->MAIN_SECURITY_DISABLEFORGETPASSLINK == 1)
284 // Patter for Password Perso
285 if ($conf->global->USER_PASSWORD_GENERATED == "Perso"){
286 
287 
288  $tabConf = explode(";",$conf->global->USER_PASSWORD_PATTERN);
289  /*$this->length2 = $tabConf[0];
290  $this->NbMaj = $tabConf[1];
291  $this->NbNum = $tabConf[2];
292  $this->NbSpe = $tabConf[3];
293  $this->NbRepeat = $tabConf[4];
294  $this->WithoutAmbi = $tabConf[5];
295  */
296  print '<br>';
297  print '<table class="noborder" width="100%">';
298  print '<tr class="liste_titre">';
299  print '<td colspan="3"> '.$langs->trans("PasswordPatternDesc").'</td>';
300  print '</tr>';
301 
302 
303  print '<tr class="oddeven">';
304  print '<td>' . $langs->trans("MinLength")."</td>";
305  print '<td colspan="2"><input type="number" value="'.$tabConf[0].'" id="minlenght" min="1"></td>';
306  print '</tr>';
307 
308 
309  print '<tr class="oddeven">';
310  print '<td>' . $langs->trans("NbMajMin")."</td>";
311  print '<td colspan="2"><input type="number" value="'.$tabConf[1].'" id="NbMajMin" min="0"></td>';
312  print '</tr>';
313 
314 
315  print '<tr class="oddeven">';
316  print '<td>' . $langs->trans("NbNumMin")."</td>";
317  print '<td colspan="2"><input type="number" value="'.$tabConf[2].'" id="NbNumMin" min="0"></td>';
318  print '</tr>';
319 
320 
321  print '<tr class="oddeven">';
322  print '<td>' . $langs->trans("NbSpeMin")."</td>";
323  print '<td colspan="2"><input type="number" value="'.$tabConf[3].'" id="NbSpeMin" min="0"></td>';
324  print '</tr>';
325 
326 
327  print '<tr class="oddeven">';
328  print '<td>' . $langs->trans("NbIteConsecutive")."</td>";
329  print '<td colspan="2"><input type="number" value="'.$tabConf[4].'" id="NbIteConsecutive" min="0"></td>';
330  print '</tr>';
331 
332 
333  print '<tr class="oddeven">';
334  print '<td>' . $langs->trans("NoAmbiCaracAutoGeneration")."</td>";
335  print '<td colspan="2"><input type="checkbox" id="NoAmbiCaracAutoGeneration" '.($tabConf[5] ? "checked" : "").' min="0"> <span id="textcheckbox">'.($tabConf[5] ? $langs->trans("Activated") : $langs->trans("Disabled")).'</span></td>';
336  print '</tr>';
337 
338  print '</table>';
339 
340  print '<br>';
341  print '<table align="right">';
342  print '<tr><td>';
343  print '<a class="button" id="linkChangePattern">'.$langs->trans("Save").'</a>';
344  print '</td></tr>';
345  print '</table>';
346  print '<br><br>';
347 
348  print '<script type="text/javascript">';
349  print ' function getStringArg(){';
350  print ' var pattern = "";';
351  print ' pattern += $("#minlenght").val() + ";";';
352  print ' pattern += $("#NbMajMin").val() + ";";';
353  print ' pattern += $("#NbNumMin").val() + ";";';
354  print ' pattern += $("#NbSpeMin").val() + ";";';
355  print ' pattern += $("#NbIteConsecutive").val() + ";";';
356  print ' pattern += $("#NoAmbiCaracAutoGeneration")[0].checked ? "1" : "0";';
357  print ' return pattern;';
358  print ' }';
359 
360  print ' function valuePossible(){';
361  print ' var length = parseInt($("#minlenght").val());';
362  print ' var length_mini = parseInt($("#NbMajMin").val()) + parseInt($("#NbNumMin").val()) + parseInt($("#NbSpeMin").val());';
363  print ' return length >= length_mini;';
364  print ' }';
365 
366  print ' function generatelink(){';
367  print ' return "security.php?action=maj_pattern&pattern="+getStringArg();';
368  print ' }';
369 
370  print ' function valuePatternChange(){';
371  print ' var lang_save = "'.$langs->trans("Save").'";';
372  print ' var lang_error = "'.$langs->trans("Error").'";';
373  print ' var lang_Disabled = "'.$langs->trans("Disabled").'";';
374  print ' var lang_Activated = "'.$langs->trans("Activated").'";';
375  print ' $("#textcheckbox").html($("#NoAmbiCaracAutoGeneration")[0].checked ? unescape(lang_Activated) : unescape(lang_Disabled));';
376  print ' if(valuePossible()){';
377  print ' $("#linkChangePattern").attr("href",generatelink()).text(lang_save);';
378  print ' }';
379  print ' else{';
380  print ' $("#linkChangePattern").attr("href", null).text(lang_error);';
381  print ' }';
382  print ' }';
383 
384  print ' $("#minlenght").change(function(){valuePatternChange();});';
385  print ' $("#NbMajMin").change(function(){valuePatternChange();});';
386  print ' $("#NbNumMin").change(function(){valuePatternChange();});';
387  print ' $("#NbSpeMin").change(function(){valuePatternChange();});';
388  print ' $("#NbIteConsecutive").change(function(){valuePatternChange();});';
389  print ' $("#NoAmbiCaracAutoGeneration").change(function(){valuePatternChange();});';
390 
391  print '</script>';
392 }
393 
394 
395 // Cryptage mot de passe
396 print '<br>';
397 $var=true;
398 print "<form method=\"post\" action=\"" . $_SERVER["PHP_SELF"] . "\">";
399 print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
400 print "<input type=\"hidden\" name=\"action\" value=\"encrypt\">";
401 
402 print '<table class="noborder" width="100%">';
403 print '<tr class="liste_titre">';
404 print '<td colspan="3">'.$langs->trans("Parameters").'</td>';
405 print '<td align="center">'.$langs->trans("Activated").'</td>';
406 print '<td align="center">'.$langs->trans("Action").'</td>';
407 print '</tr>';
408 
409 // Disable clear password in database
410 
411 print '<tr class="oddeven">';
412 print '<td colspan="3">'.$langs->trans("DoNotStoreClearPassword").'</td>';
413 print '<td align="center" width="60">';
414 if (! empty($conf->global->DATABASE_PWD_ENCRYPTED))
415 {
416  print img_picto($langs->trans("Active"),'tick');
417 }
418 print '</td>';
419 if (! $conf->global->DATABASE_PWD_ENCRYPTED)
420 {
421  print '<td align="center" width="100">';
422  print '<a href="security.php?action=activate_encrypt">'.$langs->trans("Activate").'</a>';
423  print "</td>";
424 }
425 if (! empty($conf->global->DATABASE_PWD_ENCRYPTED))
426 {
427  print '<td align="center" width="100">';
428  if ($allow_disable_encryption)
429  {
430  //On n'autorise pas l'annulation de l'encryption car les mots de passe ne peuvent pas etre decodes
431  //Do not allow "disable encryption" as passwords cannot be decrypted
432  print '<a href="security.php?action=disable_encrypt">'.$langs->trans("Disable").'</a>';
433  }
434  else
435  {
436  print '-';
437  }
438  print "</td>";
439 }
440 print "</td>";
441 print '</tr>';
442 
443 // Cryptage du mot de base de la base dans conf.php
444 
445 print '<tr class="oddeven">';
446 print '<td colspan="3">'.$langs->trans("MainDbPasswordFileConfEncrypted").'</td>';
447 print '<td align="center" width="60">';
448 if (preg_match('/crypted:/i',$dolibarr_main_db_pass) || ! empty($dolibarr_main_db_encrypted_pass))
449 {
450  print img_picto($langs->trans("Active"),'tick');
451 }
452 
453 print '</td>';
454 
455 print '<td align="center" width="100">';
456 if (empty($dolibarr_main_db_pass) && empty($dolibarr_main_db_encrypted_pass))
457 {
458  $langs->load("errors");
459  print img_warning($langs->trans("WarningPassIsEmpty"));
460 }
461 else
462 {
463  if (empty($dolibarr_main_db_encrypted_pass))
464  {
465  print '<a href="security.php?action=activate_encryptdbpassconf">'.$langs->trans("Activate").'</a>';
466  }
467  if (! empty($dolibarr_main_db_encrypted_pass))
468  {
469  print '<a href="security.php?action=disable_encryptdbpassconf">'.$langs->trans("Disable").'</a>';
470  }
471 }
472 print "</td>";
473 
474 print "</td>";
475 print '</tr>';
476 
477 
478 // Disable link "Forget password" on logon
479 
480 print '<tr class="oddeven">';
481 print '<td colspan="3">'.$langs->trans("DisableForgetPasswordLinkOnLogonPage").'</td>';
482 print '<td align="center" width="60">';
483 if(! empty($conf->global->MAIN_SECURITY_DISABLEFORGETPASSLINK))
484 {
485  print img_picto($langs->trans("Active"),'tick');
486 }
487 print '</td>';
488 if (empty($conf->global->MAIN_SECURITY_DISABLEFORGETPASSLINK))
489 {
490  print '<td align="center" width="100">';
491  print '<a href="security.php?action=activate_MAIN_SECURITY_DISABLEFORGETPASSLINK">'.$langs->trans("Activate").'</a>';
492  print "</td>";
493 }
494 if (!empty($conf->global->MAIN_SECURITY_DISABLEFORGETPASSLINK))
495 {
496  print '<td align="center" width="100">';
497  print '<a href="security.php?action=disable_MAIN_SECURITY_DISABLEFORGETPASSLINK">'.$langs->trans("Disable").'</a>';
498  print "</td>";
499 }
500 print "</td>";
501 print '</tr>';
502 
503 
504 print '</table>';
505 print '</form>';
506 
507 
508 //print '<tr><td colspan="2" align="center"><input type="submit" class="button" value="'.$langs->trans("Save").'"></td></tr>';
509 
510 print '</div>';
511 
512 
513 llxFooter();
514 
515 $db->close();
llxFooter()
Empty footer.
Definition: wrapper.php:58
img_picto($titlealt, $picto, $moreatt= '', $pictoisfullpath=false, $srconly=0, $notitle=0, $alt='', $morecss='')
Show picto whatever it's its name (generic function)
setEventMessages($mesg, $mesgs, $style='mesgs')
Set event messages in dol_events session object.
if(!GETPOST('transkey')&&!GETPOST('transphrase')) else
View.
Definition: notice.php:43
dol_fiche_head($links=array(), $active='0', $title='', $notab=0, $picto='', $pictoisfullpath=0, $morehtmlright='')
Show tab header of a card.
dolibarr_set_const($db, $name, $value, $type='chaine', $visible=0, $note='', $entity=1)
Insert a parameter (key,value) into database (delete old key then insert it again).
Definition: admin.lib.php:485
dol_print_error($db='', $error='', $errors=null)
Affiche message erreur system avec toutes les informations pour faciliter le diagnostic et la remonte...
if(empty($reshook)) $form
View.
Definition: perms.php:103
GETPOST($paramname, $check='none', $method=0, $filter=NULL, $options=NULL, $noreplace=0)
Return value of a param into GET or POST supervariable.
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 generation of HTML components Only common components must be here.
img_warning($titlealt= 'default', $moreatt= '')
Show warning logo.
if(GETPOST('button_removefilter_x','alpha')||GETPOST('button_removefilter.x','alpha')||GETPOST('button_removefilter','alpha')) if($action=="save"&&empty($cancel)) if(preg_match('/set_(.*)/', $action, $reg)) if(preg_match('/del_(.*)/', $action, $reg) $wikihelp)
View.
Definition: agenda.php:143
dolibarr_del_const($db, $name, $entity=1)
Effacement d'une constante dans la base de donnees.
Definition: admin.lib.php:410
load_fiche_titre($titre, $morehtmlright='', $picto='title_generic.png', $pictoisfullpath=0, $id=0, $morecssontable='', $morehtmlcenter='')
Load a title with picto.
llxHeader()
Empty header.
Definition: wrapper.php:46
dol_encode($chain)
Encode a string with base 64 algorithm + specific change Code of this function is useless and we shou...
security_prepare_head()
Prepare array with list of tabs.
Definition: admin.lib.php:581
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:1013
encodedecode_dbpassconf($level=0)
Encode or decode database password in config file.
dol_hash($chain, $type='0')
Returns a hash of a string.