You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ipa-healthcheck/SOURCES/0004-Catch-exceptions-durin...

143 lines
4.9 KiB

From 4906c52b629bfce275558d4701c083f4c020ef32 Mon Sep 17 00:00:00 2001
From: Rob Crittenden <rcritten@redhat.com>
Date: Fri, 30 Jun 2023 14:35:40 -0400
Subject: [PATCH] Catch exceptions during user/group name lookup in FileCheck
It's possible that one or more of the allowed users/groups
in a file check do not exist on the system. Catch this
exception and try to proceed as best as possible.
https://github.com/freeipa/freeipa-healthcheck/issues/296
Signed-off-by: Rob Crittenden <rcritten@redhat.com>
---
src/ipahealthcheck/core/files.py | 33 +++++++++++++++++++++++----
tests/test_core_files.py | 38 ++++++++++++++++++++++++++++++++
2 files changed, 67 insertions(+), 4 deletions(-)
diff --git a/src/ipahealthcheck/core/files.py b/src/ipahealthcheck/core/files.py
index 59e8b76..85d42bc 100644
--- a/src/ipahealthcheck/core/files.py
+++ b/src/ipahealthcheck/core/files.py
@@ -3,12 +3,15 @@
#
import grp
+import logging
import os
import pwd
from ipahealthcheck.core import constants
from ipahealthcheck.core.plugin import Result, duration
+logger = logging.getLogger()
+
class FileCheck:
"""Generic check to validate permission and ownership of files
@@ -77,14 +80,25 @@ class FileCheck:
found = False
for o in owner:
- fowner = pwd.getpwnam(o)
+ try:
+ fowner = pwd.getpwnam(o)
+ except Exception as e:
+ logging.debug('user lookup "%s" for "%s" failed: %s',
+ o, path, e)
+ continue
if fowner.pw_uid == stat.st_uid:
found = True
break
if not found:
- actual = pwd.getpwuid(stat.st_uid)
key = '%s_owner' % path.replace('/', '_')
+ try:
+ actual = pwd.getpwuid(stat.st_uid)
+ except Exception:
+ yield Result(self, constants.WARNING, key=key,
+ path=path, type='owner', expected=owner,
+ got='Unknown uid %s' % stat.st_uid)
+ continue
if len(owner) == 1:
msg = 'Ownership of %s is %s and should ' \
'be %s' % \
@@ -104,14 +118,25 @@ class FileCheck:
found = False
for g in group:
- fgroup = grp.getgrnam(g)
+ try:
+ fgroup = grp.getgrnam(g)
+ except Exception as e:
+ logging.debug('group lookup "%s" for "%s" failed: %s',
+ g, path, e)
+ continue
if fgroup.gr_gid == stat.st_gid:
found = True
break
if not found:
key = '%s_group' % path.replace('/', '_')
- actual = grp.getgrgid(stat.st_gid)
+ try:
+ actual = grp.getgrgid(stat.st_gid)
+ except Exception:
+ yield Result(self, constants.WARNING, key=key,
+ path=path, type='group', expected=group,
+ got='Unknown gid %s' % stat.st_gid)
+ continue
if len(group) == 1:
msg = 'Group of %s is %s and should ' \
'be %s' % \
diff --git a/tests/test_core_files.py b/tests/test_core_files.py
index 6e3ec38..924d7fa 100644
--- a/tests/test_core_files.py
+++ b/tests/test_core_files.py
@@ -197,3 +197,41 @@ def test_files_not_found(mock_exists):
for result in my_results.results:
assert result.result == constants.SUCCESS
assert result.kw.get('msg') == 'File does not exist'
+
+
+@patch('os.stat')
+@patch('pwd.getpwnam')
+@patch('pwd.getpwuid')
+def test_files_owner_not_found(mock_pwuid, mock_pwnam, mock_stat):
+ mock_pwuid.side_effect = KeyError('getpwnam(): name not found')
+ mock_pwnam.side_effect = KeyError('getpwuid(): uid not found')
+ mock_stat.return_value = make_stat()
+
+ f = FileCheck()
+ f.files = files
+
+ results = capture_results(f)
+
+ my_results = get_results(results, 'owner')
+ for result in my_results.results:
+ assert result.result == constants.WARNING
+ assert result.kw.get('got') == 'Unknown uid 0'
+
+
+@patch('os.stat')
+@patch('grp.getgrnam')
+@patch('grp.getgrgid')
+def test_files_group_not_found(mock_grgid, mock_grnam, mock_stat):
+ mock_grgid.side_effect = KeyError('getgrnam(): name not found')
+ mock_grnam.side_effect = KeyError('getgruid(): gid not found')
+ mock_stat.return_value = make_stat()
+
+ f = FileCheck()
+ f.files = files
+
+ results = capture_results(f)
+
+ my_results = get_results(results, 'group')
+ for result in my_results.results:
+ assert result.result == constants.WARNING
+ assert result.kw.get('got') == 'Unknown gid 0'
--
2.41.0