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