diff --git a/htdocs/admin/system/security.php b/htdocs/admin/system/security.php index fd8f0a694fc..6291486f54d 100644 --- a/htdocs/admin/system/security.php +++ b/htdocs/admin/system/security.php @@ -23,6 +23,7 @@ require '../../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/memory.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/geturl.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/security2.lib.php'; @@ -127,6 +128,7 @@ if ($test) { } print '
'; +print '
'; print '
'; print load_fiche_titre($langs->trans("ConfigurationFile").' ('.$conffile.')', '', 'folder'); @@ -148,13 +150,38 @@ print ''.$langs->trans("dolibarr_main_restrict_ip").': '.$dolib }*/ print '
'; +print '
'; print '
'; print '
'; print load_fiche_titre($langs->trans("PermissionsOnFiles"), '', 'folder'); print ''.$langs->trans("PermissionsOnFilesInWebRoot").': '; -// TODO Check permission are read only except for custom dir -print 'TODO'; +$arrayoffilesinroot = dol_dir_list(DOL_DOCUMENT_ROOT, 'all', 1, '', array('custom\/'), 'name', SORT_ASC, 4, 1, '', 1); +$fileswithwritepermission = array(); +foreach ($arrayoffilesinroot as $fileinroot) { + // Test permission on file + if ($fileinroot['perm'] & 0222) { + $fileswithwritepermission[] = $fileinroot['relativename']; + } +} +if (empty($fileswithwritepermission)) { + print img_picto('', 'tick').' '.$langs->trans("NoWritableFilesFoundIntoRootDir"); +} else { + print img_warning().' '.$langs->trans("SomeFilesOrDirInRootAreWritable"); + print '
'.$langs->trans("Example").': '; + $i = 0; + foreach ($fileswithwritepermission as $filewithwritepermission) { + if ($i > 0) { + print ', '; + } + print ''.$filewithwritepermission.''; + if ($i > 20) { + print ' ...'; + break; + } + $i++; + } +} print '
'; print ''.$langs->trans("PermissionsOnFile", $conffile).': '; // $conffile is defined into filefunc.inc.php @@ -180,6 +207,7 @@ print '
'; print '
'; +print '
'; print '
'; print load_fiche_titre($langs->trans("Modules"), '', 'folder'); @@ -209,6 +237,7 @@ if ($test) { } print '
'; +print '
'; print '
'; print '
'; print load_fiche_titre($langs->trans("Menu").' '.$langs->trans("SecuritySetup"), '', 'folder'); @@ -228,7 +257,6 @@ if ($conf->global->MAIN_SECURITY_HASH_ALGO != 'password_hash') { print '
'; } print '
'; -// TODO print ''.$langs->trans("AntivirusEnabledOnUpload").': '; print empty($conf->global->MAIN_ANTIVIRUS_COMMAND) ? '' : img_picto('', 'tick').' '; @@ -246,30 +274,28 @@ print '
'; $securityevent = new Events($db); $eventstolog = $securityevent->eventstolog; -print ''.$langs->trans("LogEvents").': '; -// Loop on each event type -$i = 0; -foreach ($eventstolog as $key => $arr) { - if ($arr['id']) { - $key = 'MAIN_LOGEVENTS_'.$arr['id']; - $value = empty($conf->global->$key) ? '' : $conf->global->$key; - if ($value) { - if ($i > 0) { - print ', '; +print ''.$langs->trans("AuditedSecurityEvents").': '; +if (!empty($eventstolog) && is_array($eventstolog)) { + // Loop on each event type + $i = 0; + foreach ($eventstolog as $key => $arr) { + if ($arr['id']) { + $key = 'MAIN_LOGEVENTS_'.$arr['id']; + $value = empty($conf->global->$key) ? '' : $conf->global->$key; + if ($value) { + if ($i > 0) { + print ', '; + } + print ''.$key.''; + $i++; } - print ''.$key.''; - $i++; } } +} else { + print img_warning().' '.$langs->trans("NoSecurityEventsAreAduited", $langs->transnoentities("Home").' - '.$langs->transnoentities("Setup").' - '.$langs->transnoentities("Audit")); } - - - - - - // End of page llxFooter(); $db->close(); diff --git a/htdocs/core/lib/files.lib.php b/htdocs/core/lib/files.lib.php index 782b0ec4694..755cd8674df 100644 --- a/htdocs/core/lib/files.lib.php +++ b/htdocs/core/lib/files.lib.php @@ -50,7 +50,7 @@ function dol_basename($pathfile) * @param array $excludefilter Array of Regex for exclude filter (example: array('(\.meta|_preview.*\.png)$','^\.')). Exclude is checked both into fullpath and into basename (So '^xxx' may exclude 'xxx/dirscanned/...' and dirscanned/xxx'). * @param string $sortcriteria Sort criteria ('','fullname','relativename','name','date','size') * @param string $sortorder Sort order (SORT_ASC, SORT_DESC) - * @param int $mode 0=Return array minimum keys loaded (faster), 1=Force all keys like date and size to be loaded (slower), 2=Force load of date only, 3=Force load of size only + * @param int $mode 0=Return array minimum keys loaded (faster), 1=Force all keys like date and size to be loaded (slower), 2=Force load of date only, 3=Force load of size only, 4=Force load of perm * @param int $nohook Disable all hooks * @param string $relativename For recursive purpose only. Must be "" at first call. * @param string $donotfollowsymlinks Do not follow symbolic links @@ -67,6 +67,7 @@ function dol_dir_list($path, $types = "all", $recursive = 0, $filter = "", $excl $loaddate = ($mode == 1 || $mode == 2) ?true:false; $loadsize = ($mode == 1 || $mode == 3) ?true:false; + $loadperm = ($mode == 1 || $mode == 4) ?true:false; // Clean parameters $path = preg_replace('/([\\/]+)$/i', '', $path); @@ -141,6 +142,9 @@ function dol_dir_list($path, $types = "all", $recursive = 0, $filter = "", $excl if ($loadsize || $sortcriteria == 'size') { $filesize = dol_filesize($path."/".$file); } + if ($loadperm || $sortcriteria == 'perm') { + $fileperm = dol_fileperm($path."/".$file); + } if (!$filter || preg_match('/'.$filter.'/i', $file)) { // We do not search key $filter into all $path, only into $file part $reg = array(); @@ -154,6 +158,7 @@ function dol_dir_list($path, $types = "all", $recursive = 0, $filter = "", $excl "fullname" => $path.'/'.$file, "date" => $filedate, "size" => $filesize, + "perm" => $fileperm, "type" => 'dir' ); } @@ -587,6 +592,18 @@ function dol_filemtime($pathoffile) return @filemtime($newpathoffile); // @Is to avoid errors if files does not exists } +/** + * Return permissions of a file + * + * @param string $pathoffile Path of file + * @return integer File permissions + */ +function dol_fileperm($pathoffile) +{ + $newpathoffile = dol_osencode($pathoffile); + return fileperms($newpathoffile); +} + /** * Make replacement of strings into a file. * diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index cec1e07b823..5d78f312917 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -1184,7 +1184,8 @@ SetupDescription2=The following two sections are mandatory (the two first entrie SetupDescription3=%s -> %s

Basic parameters used to customize the default behavior of your application (e.g for country-related features). SetupDescription4=%s -> %s

This software is a suite of many modules/applications. The modules related to your needs must be enabled and configured. Menu entries will appears with the activation of these modules. SetupDescription5=Other Setup menu entries manage optional parameters. -LogEvents=Security audit events +AuditedSecurityEvents=Security events that are audited +NoSecurityEventsAreAduited=No security events are audited. You can enable them from menu %s Audit=Audit InfoDolibarr=About Dolibarr InfoBrowser=About Browser