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