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