Blame SOURCES/sos-bz1985037-cleaner-AD-users-obfuscation.patch

2ed6e8
From 7e471676fe41dab155a939c60446cc7b7dab773b Mon Sep 17 00:00:00 2001
2ed6e8
From: Jake Hunsaker <jhunsake@redhat.com>
2ed6e8
Date: Tue, 20 Jul 2021 11:09:29 -0400
2ed6e8
Subject: [PATCH] [username parser] Load usernames from `last` for LDAP users
2ed6e8
2ed6e8
AD/LDAP users are not reported into `lastlog` generally, however they
2ed6e8
are reported in `last`. Conversely, `last` does not report local users
2ed6e8
who have not logged in but still exist.
2ed6e8
2ed6e8
In order to obfuscate both kinds of users, we need to look at both
2ed6e8
sources.
2ed6e8
2ed6e8
For this, first allow parsers to specify multiple prep files. Second,
2ed6e8
update the username parser to search through all `lastlog` collections
2ed6e8
as well as the `last` collection.
2ed6e8
2ed6e8
Also includes a small update to the username parser's prep loading logic
2ed6e8
to ensure we are iterating over each username discovered only once.
2ed6e8
2ed6e8
Signed-off-by: Jake Hunsaker <jhunsake@redhat.com>
2ed6e8
---
2ed6e8
 sos/cleaner/__init__.py                | 38 ++++++++++++++------------
2ed6e8
 sos/cleaner/parsers/__init__.py        |  2 +-
2ed6e8
 sos/cleaner/parsers/username_parser.py | 24 +++++++++++++---
2ed6e8
 3 files changed, 42 insertions(+), 22 deletions(-)
2ed6e8
2ed6e8
diff --git a/sos/cleaner/__init__.py b/sos/cleaner/__init__.py
2ed6e8
index ca5f93e5..6aadfe79 100644
2ed6e8
--- a/sos/cleaner/__init__.py
2ed6e8
+++ b/sos/cleaner/__init__.py
2ed6e8
@@ -518,23 +518,27 @@ third party.
2ed6e8
             for _parser in self.parsers:
2ed6e8
                 if not _parser.prep_map_file:
2ed6e8
                     continue
2ed6e8
-                _arc_path = os.path.join(_arc_name, _parser.prep_map_file)
2ed6e8
-                try:
2ed6e8
-                    if is_dir:
2ed6e8
-                        _pfile = open(_arc_path, 'r')
2ed6e8
-                        content = _pfile.read()
2ed6e8
-                    else:
2ed6e8
-                        _pfile = archive.extractfile(_arc_path)
2ed6e8
-                        content = _pfile.read().decode('utf-8')
2ed6e8
-                    _pfile.close()
2ed6e8
-                    if isinstance(_parser, SoSUsernameParser):
2ed6e8
-                        _parser.load_usernames_into_map(content)
2ed6e8
-                    for line in content.splitlines():
2ed6e8
-                        if isinstance(_parser, SoSHostnameParser):
2ed6e8
-                            _parser.load_hostname_into_map(line)
2ed6e8
-                        self.obfuscate_line(line)
2ed6e8
-                except Exception as err:
2ed6e8
-                    self.log_debug("Could not prep %s: %s" % (_arc_path, err))
2ed6e8
+                if isinstance(_parser.prep_map_file, str):
2ed6e8
+                    _parser.prep_map_file = [_parser.prep_map_file]
2ed6e8
+                for parse_file in _parser.prep_map_file:
2ed6e8
+                    _arc_path = os.path.join(_arc_name, parse_file)
2ed6e8
+                    try:
2ed6e8
+                        if is_dir:
2ed6e8
+                            _pfile = open(_arc_path, 'r')
2ed6e8
+                            content = _pfile.read()
2ed6e8
+                        else:
2ed6e8
+                            _pfile = archive.extractfile(_arc_path)
2ed6e8
+                            content = _pfile.read().decode('utf-8')
2ed6e8
+                        _pfile.close()
2ed6e8
+                        if isinstance(_parser, SoSUsernameParser):
2ed6e8
+                            _parser.load_usernames_into_map(content)
2ed6e8
+                        for line in content.splitlines():
2ed6e8
+                            if isinstance(_parser, SoSHostnameParser):
2ed6e8
+                                _parser.load_hostname_into_map(line)
2ed6e8
+                            self.obfuscate_line(line)
2ed6e8
+                    except Exception as err:
2ed6e8
+                        self.log_debug("Could not prep %s: %s"
2ed6e8
+                                       % (_arc_path, err))
2ed6e8
 
2ed6e8
     def obfuscate_report(self, report):
2ed6e8
         """Individually handle each archive or directory we've discovered by
2ed6e8
diff --git a/sos/cleaner/parsers/__init__.py b/sos/cleaner/parsers/__init__.py
2ed6e8
index 3076db39..af6e375e 100644
2ed6e8
--- a/sos/cleaner/parsers/__init__.py
2ed6e8
+++ b/sos/cleaner/parsers/__init__.py
2ed6e8
@@ -50,7 +50,7 @@ class SoSCleanerParser():
2ed6e8
     skip_line_patterns = []
2ed6e8
     skip_files = []
2ed6e8
     map_file_key = 'unset'
2ed6e8
-    prep_map_file = 'unset'
2ed6e8
+    prep_map_file = []
2ed6e8
 
2ed6e8
     def __init__(self, conf_file=None):
2ed6e8
         # attempt to load previous run data into the mapping for the parser
2ed6e8
diff --git a/sos/cleaner/parsers/username_parser.py b/sos/cleaner/parsers/username_parser.py
2ed6e8
index 96ce5f0c..b142e371 100644
2ed6e8
--- a/sos/cleaner/parsers/username_parser.py
2ed6e8
+++ b/sos/cleaner/parsers/username_parser.py
2ed6e8
@@ -25,13 +25,24 @@ class SoSUsernameParser(SoSCleanerParser
2ed6e8
 
2ed6e8
     name = 'Username Parser'
2ed6e8
     map_file_key = 'username_map'
2ed6e8
-    prep_map_file = 'sos_commands/login/lastlog_-u_1000-60000'
2ed6e8
+    prep_map_file = [
2ed6e8
+        'sos_commands/login/lastlog_-u_1000-60000',
2ed6e8
+        'sos_commands/login/lastlog_-u_60001-65536',
2ed6e8
+        'sos_commands/login/lastlog_-u_65537-4294967295',
2ed6e8
+        # AD users will be reported here, but favor the lastlog files since
2ed6e8
+        # those will include local users who have not logged in
2ed6e8
+        'sos_commands/login/last'
2ed6e8
+    ]
2ed6e8
     regex_patterns = []
2ed6e8
     skip_list = [
2ed6e8
         'core',
2ed6e8
         'nobody',
2ed6e8
         'nfsnobody',
2ed6e8
-        'root'
2ed6e8
+        'shutdown',
2ed6e8
+        'reboot',
2ed6e8
+        'root',
2ed6e8
+        'ubuntu',
2ed6e8
+        'wtmp'
2ed6e8
     ]
2ed6e8
 
2ed6e8
     def __init__(self, conf_file=None, opt_names=None):
2ed6e8
@@ -44,11 +54,17 @@ class SoSUsernameParser(SoSCleanerParser):
2ed6e8
         """Since we don't get the list of usernames from a straight regex for
2ed6e8
         this parser, we need to override the initial parser prepping here.
2ed6e8
         """
2ed6e8
+        users = set()
2ed6e8
         for line in content.splitlines()[1:]:
2ed6e8
-            user = line.split()[0]
2ed6e8
+            try:
2ed6e8
+                user = line.split()[0]
2ed6e8
+            except Exception:
2ed6e8
+                continue
2ed6e8
             if user in self.skip_list:
2ed6e8
                 continue
2ed6e8
-            self.mapping.get(user)
2ed6e8
+            users.add(user)
2ed6e8
+        for each in users:
2ed6e8
+            self.mapping.get(each)
2ed6e8
 
2ed6e8
     def parse_line(self, line):
2ed6e8
         count = 0
2ed6e8
-- 
2ed6e8
2.31.1
2ed6e8