Files
ansible-testing/methodologies/ansible/playbooks/templates/test_file_check.yml
T

74 lines
3.1 KiB
YAML

---
# ══════════════════════════════════════════════════════════════════════
# TEMPLATE: File Permission / Ownership Check
# ══════════════════════════════════════════════════════════════════════
#
# Uses ansible.builtin.stat — no shell command needed.
# Prefer this over shelling out to stat(1) for file attribute checks.
# The stat module returns a structured dict with typed values, which
# makes the 'passed' expression straightforward and readable.
#
# Useful stat attributes:
# stat.exists — bool: file is present
# stat.mode — string: octal permissions, e.g. '0640'
# stat.pw_name — string: owning user name, e.g. 'root'
# stat.gr_name — string: owning group name, e.g. 'shadow'
# stat.size — int: file size in bytes
# stat.isreg — bool: is a regular file
# stat.isdir — bool: is a directory
# stat.islnk — bool: is a symlink
#
# Common 'passed' expression patterns:
#
# # File exists with exact owner/group/mode:
# 'passed': (
# _stat.stat.exists and
# _stat.stat.pw_name == 'root' and
# _stat.stat.gr_name == 'root' and
# _stat.stat.mode == '0640'
# ),
#
# # File must NOT exist:
# 'passed': not _stat.stat.exists,
#
# # File must be a regular file (not a symlink) with tight permissions:
# 'passed': (
# _stat.stat.exists and
# _stat.stat.isreg and
# not _stat.stat.islnk and
# _stat.stat.mode in ['0400', '0440', '0600']
# ),
#
# ══════════════════════════════════════════════════════════════════════
# ── SUITE_ID: SHORT_DESCRIPTION ─────────────────────────────────────
- block:
- name: "Gather: Stat /path/to/file"
ansible.builtin.stat:
path: /path/to/file
register: _stat
- name: "Evaluate: TEST_ID"
ansible.builtin.set_fact:
test_results: "{{ test_results + [{
'test_id': 'TEST_ID',
'category': 'FR_NUMBER — CATEGORY_NAME',
'requirement': 'SR X.Y — REQUIREMENT_NAME',
'description': '/path/to/file shall be owned by root:root with mode 0640',
'passed': (
_stat.stat.exists and
_stat.stat.pw_name == 'root' and
_stat.stat.gr_name == 'root' and
_stat.stat.mode == '0640'
),
'expected': 'root:root 0640',
'actual': (
(_stat.stat.pw_name + ':' + _stat.stat.gr_name + ' ' + _stat.stat.mode)
if _stat.stat.exists else 'FILE NOT FOUND'
),
'severity': 'high',
'remediation': 'chown root:root /path/to/file && chmod 0640 /path/to/file'
}] }}"
ignore_errors: yes