Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions tests/system/data/test_grpck/group
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
root:x:0:
daemon:x:1:
tgroup1:x:1001:
3 changes: 3 additions & 0 deletions tests/system/data/test_grpck/gshadow
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
root:*:root:
daemon:*::
tgroup1:$1$yQnIAZWV$gDAMB2IkqaONgrQiRdo4y.::
3 changes: 3 additions & 0 deletions tests/system/data/test_pwck/group
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
root:x:0:
daemon:x:1:
ci:x:1000:
3 changes: 3 additions & 0 deletions tests/system/data/test_pwck/passwd
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
ci:x:1000:1000::/home/ci:/bin/bash
3 changes: 3 additions & 0 deletions tests/system/data/test_pwck/shadow
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
root:$1$NBLBLIXb$WUgojj1bNuxWEADQGt1m9.:19999:0:99999:7:::
daemon:*:19999:0:99999:7:::
ci:!:20692:0:99999:7:::
32 changes: 32 additions & 0 deletions tests/system/framework/roles/shadow.py
Original file line number Diff line number Diff line change
Expand Up @@ -548,3 +548,35 @@ def vipw(self, *args, editor_script: str | None = None) -> ProcessResult:
self.host.discard_file(file_to_discard)

return result

def pwck(self, *args) -> ProcessResult:
"""
Verify the integrity of password files.

The pwck command verifies that all entries in /etc/passwd and /etc/shadow
have the proper format and contain valid data.
"""
cmd_args = " ".join(args)
self.logger.info(f"Running pwck on {self.host.hostname}")
cmd = self.host.conn.run(f"pwck {cmd_args}", log_level=ProcessLogLevel.Error)

self.host.discard_file("/etc/passwd")
self.host.discard_file("/etc/shadow")

return cmd

def grpck(self, *args) -> ProcessResult:
"""
Verify the integrity of group files.

The grpck command verifies that all entries in /etc/group and /etc/gshadow
have the proper format and contain valid data.
"""
cmd_args = " ".join(args)
self.logger.info(f"Running grpck on {self.host.hostname}")
cmd = self.host.conn.run(f"grpck {cmd_args}", log_level=ProcessLogLevel.Error)

self.host.discard_file("/etc/group")
self.host.discard_file("/etc/gshadow")

return cmd
40 changes: 40 additions & 0 deletions tests/system/tests/test_grpck.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
"""
Test grpck
"""

from __future__ import annotations

from pathlib import Path

import pytest

from framework.roles.shadow import Shadow
from framework.topology import KnownTopology


@pytest.mark.topology(KnownTopology.Shadow)
def test_grpck__validates_clean_files(shadow: Shadow):
"""
:title: grpck validates clean group files in read-only mode
:setup:
1. Remove existing group and gshadow files
2. Copy group and gshadow files
:steps:
1. Run grpck integrity check in read-only mode
2. Verify command exit status
:expectedresults:
1. grpck completes successfully
2. Command succeeds
:customerscenario: False
"""
shadow.host.fs.rm("/etc/group")
shadow.host.fs.rm("/etc/gshadow")

test_dir = Path(__file__).parent.parent
group_file = test_dir / "data" / "test_grpck" / "group"
shadow.host.fs.upload(str(group_file.resolve()), "/etc/group")
gshadow_file = test_dir / "data" / "test_grpck" / "gshadow"
shadow.host.fs.upload(str(gshadow_file.resolve()), "/etc/gshadow")

result = shadow.grpck("-r")
assert result.rc == 0
48 changes: 48 additions & 0 deletions tests/system/tests/test_pwck.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
"""
Test pwck
"""

from __future__ import annotations

from pathlib import Path

import pytest

from framework.roles.shadow import Shadow
from framework.topology import KnownTopology


@pytest.mark.topology(KnownTopology.Shadow)
def test_pwck__validates_clean_files(shadow: Shadow):
"""
:title: pwck validates clean password files in read-only mode
:setup:
1. Remove existing passwd, shadow and group files
2. Copy passwd, shadow and group files
:steps:
1. Run pwck integrity check in read-only mode
2. Verify command exit status
:expectedresults:
1. pwck completes successfully
2. Command succeeds
:cleanup:
1. Restore original /etc/group
:customerscenario: False
"""
shadow.host.fs.rm("/etc/passwd")
shadow.host.fs.rm("/etc/shadow")
shadow.host.fs.rm("/etc/group")

test_dir = Path(__file__).parent.parent
passwd_file = test_dir / "data" / "test_pwck" / "passwd"
shadow.host.fs.upload(str(passwd_file.resolve()), "/etc/passwd")
shadow_file = test_dir / "data" / "test_pwck" / "shadow"
shadow.host.fs.upload(str(shadow_file.resolve()), "/etc/shadow")
group_file = test_dir / "data" / "test_pwck" / "group"
shadow.host.fs.upload(str(group_file.resolve()), "/etc/group")

result = shadow.pwck("-r")
assert result.rc == 0

# The modified /etc/group will cause the test to fail during teardown, thus restore it
shadow.host.fs.restore("/etc/group")
Loading