From cca04c1e1fdc97632cdefdc1d1d7a3dea9cb4aea Mon Sep 17 00:00:00 2001
From: Pavel Moravec <pmoravec@redhat.com>
Date: Wed, 28 Jun 2023 11:49:56 +0200
Subject: [PATCH 1/2] [clean] Respect permissions of sanitised files

When copying files we applied a substitution in, we must replace just
original file content (shutil.copyfile) and not also its stat data
(shutil.copy).

Resolves: #3292

Signed-off-by: Pavel Moravec <pmoravec@redhat.com>
---
 sos/cleaner/__init__.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sos/cleaner/__init__.py b/sos/cleaner/__init__.py
index feeedf66..fbcaa9c3 100644
--- a/sos/cleaner/__init__.py
+++ b/sos/cleaner/__init__.py
@@ -778,7 +778,7 @@ third party.
                                        % (short_name, err), caller=arc_name)
             tfile.seek(0)
             if subs:
-                shutil.copy(tfile.name, filename)
+                shutil.copyfile(tfile.name, filename)
             tfile.close()
 
         _ob_short_name = self.obfuscate_string(short_name.split('/')[-1])
-- 
2.31.1


From fc1489a621108d3613d3337489a64950e52d77c3 Mon Sep 17 00:00:00 2001
From: Pavel Moravec <pmoravec@redhat.com>
Date: Thu, 29 Jun 2023 22:57:46 +0200
Subject: [PATCH 2/2] [tests] add test for #3292

Add a test that cleaner keeps permissions of a sanitised file

Relevant to: #3292

Signed-off-by: Pavel Moravec <pmoravec@redhat.com>
---
 .../basic_function_tests/report_with_mask.py   | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/tests/cleaner_tests/basic_function_tests/report_with_mask.py b/tests/cleaner_tests/basic_function_tests/report_with_mask.py
index 7c4d3905..baee836a 100644
--- a/tests/cleaner_tests/basic_function_tests/report_with_mask.py
+++ b/tests/cleaner_tests/basic_function_tests/report_with_mask.py
@@ -9,6 +9,7 @@
 from sos_tests import StageOneReportTest, StageTwoReportTest
 
 import re
+from os import stat
 
 
 class ReportWithMask(StageOneReportTest):
@@ -18,6 +19,17 @@ class ReportWithMask(StageOneReportTest):
     """
 
     sos_cmd = '--mask -o host,networking'
+    hosts_obfuscated = None
+
+    def pre_sos_setup(self):
+        # obfuscate a random word from /etc/hosts and ensure the updated
+        # sanitised file has same permissions (a+r)
+        try:
+            self.hosts_obfuscated = open('/etc/hosts').read().strip('#\n').split()[-1]
+        except (FileNotFoundError, IndexError) as e:
+            self.warning(f"Unable to process /etc/hosts: {e}")
+        if self.hosts_obfuscated:
+            self.sos_cmd += f' --keywords={self.hosts_obfuscated}'
 
     def test_mask_was_run(self):
         self.assertOutputContains('Beginning obfuscation')
@@ -53,6 +65,12 @@ class ReportWithMask(StageOneReportTest):
                 mac = line.strip().split()[1]
                 assert mac.startswith('53:4f:53'), "Found unobfuscated mac addr %s" % mac
 
+    def test_perms_unchanged_on_modified_file(self):
+        if self.hosts_obfuscated:
+            imode_orig = stat('/etc/hosts').st_mode
+            imode_obfuscated = stat(self.get_name_in_archive('etc/hosts')).st_mode
+            self.assertEqual(imode_orig, imode_obfuscated)
+
 
 class ReportWithCleanedKeywords(StageOneReportTest):
     """Testing for obfuscated keywords provided by the user
-- 
2.31.1