# SPDX-FileCopyrightText: Huawei Inc. # # SPDX-License-Identifier: MIT import os import oe import unittest from oeqa.selftest.case import OESelftestTestCase from oeqa.utils.commands import bitbake, get_bb_vars class ShadowUtilsTidyFiles(OESelftestTestCase): """ Check if shadow image rootfs files are tidy. The tests are focused on testing the functionality provided by the 'tidy_shadowutils_files' rootfs postprocess command (via SORT_PASSWD_POSTPROCESS_COMMAND). """ def sysconf_build(self): """ Verify if shadow tidy files tests are to be run and if yes, build a test image and return its sysconf rootfs path. """ test_image = "core-image-minimal" config = 'IMAGE_CLASSES += "extrausers"\n' config += 'EXTRA_USERS_PARAMS = "groupadd -g 1000 oeqatester; "\n' config += 'EXTRA_USERS_PARAMS += "useradd -p \'\' -u 1000 -N -g 1000 oeqatester; "\n' self.write_config(config) vars = get_bb_vars(("IMAGE_ROOTFS", "SORT_PASSWD_POSTPROCESS_COMMAND", "sysconfdir"), test_image) passwd_postprocess_cmd = vars["SORT_PASSWD_POSTPROCESS_COMMAND"] self.assertIsNotNone(passwd_postprocess_cmd) if (passwd_postprocess_cmd.strip() != 'tidy_shadowutils_files;'): raise unittest.SkipTest("Testcase skipped as 'tidy_shadowutils_files' " "rootfs post process command is not the set SORT_PASSWD_POSTPROCESS_COMMAND.") rootfs = vars["IMAGE_ROOTFS"] self.assertIsNotNone(rootfs) sysconfdir = vars["sysconfdir"] bitbake(test_image) self.assertIsNotNone(sysconfdir) return oe.path.join(rootfs, sysconfdir) def test_shadowutils_backup_files(self): """ Test that the rootfs doesn't include any known shadow backup files. """ backup_files = ( 'group-', 'gshadow-', 'passwd-', 'shadow-', 'subgid-', 'subuid-', ) rootfs_sysconfdir = self.sysconf_build() found = [] for backup_file in backup_files: backup_filepath = oe.path.join(rootfs_sysconfdir, backup_file) if os.path.exists(backup_filepath): found.append(backup_file) if (found): raise Exception('The following shadow backup files were found in ' 'the rootfs: %s' % found) def test_shadowutils_sorted_files(self): """ Test that the 'passwd' and the 'group' shadow utils files are ordered by ID. """ files = ( 'passwd', 'group', ) rootfs_sysconfdir = self.sysconf_build() unsorted = [] for file in files: filepath = oe.path.join(rootfs_sysconfdir, file) with open(filepath, 'rb') as f: ids = [] lines = f.readlines() for line in lines: entries = line.split(b':') ids.append(int(entries[2])) if (ids != sorted(ids)): unsorted.append(file) if (unsorted): raise Exception("The following files were not sorted by ID as expected: %s" % unsorted)