From 89fe674ca559f41f165de1e7a1c49175b9632d6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20V=C3=A1vra?= Date: Mon, 4 May 2026 16:35:09 +0200 Subject: [PATCH] Fix violations of static analysis for pytests Enable static analysis on pushes and pull requests. Fix some isort and typing issues. Switch static analysis to ruff. --- .github/workflows/ci.yml | 41 +++ .github/workflows/static-code-analysis.yml | 76 ----- pytest/pyproject.toml | 24 +- pytest/tests/test_basic.py | 311 ++++++++++----------- pytest/tests/test_misc_issues.py | 51 ++-- pytest/tests/test_security.py | 10 +- pytest/tests/test_sudo.py | 15 +- 7 files changed, 253 insertions(+), 275 deletions(-) delete mode 100644 .github/workflows/static-code-analysis.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e374f62..1adf36f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,6 +8,47 @@ concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true jobs: + static-code-analysis: + runs-on: ubuntu-latest + permissions: + contents: read + steps: + - uses: actions/setup-python@v5 + with: + python-version: 3.x + + - name: Checkout repository + uses: actions/checkout@v6 + + - name: Setup virtual environment + working-directory: ./pytest + run: | + sudo apt-get update + + # Install dependencies for python-ldap + sudo apt-get install -y libsasl2-dev python3-dev libldap2-dev libssl-dev libssh-dev + + pip3 install virtualenv + python3 -m venv .venv + source .venv/bin/activate + pip3 install -r ./requirements.txt + pip3 install ruff mypy + + - name: Ruff check + if: always() + working-directory: ./pytest + run: source .venv/bin/activate && ruff check . + + - name: Ruff format + if: always() + working-directory: ./pytest + run: source .venv/bin/activate && ruff format --check . + + - name: mypy + if: always() + working-directory: ./pytest + run: source .venv/bin/activate && mypy --install-types --non-interactive tests + pytest: strategy: fail-fast: false diff --git a/.github/workflows/static-code-analysis.yml b/.github/workflows/static-code-analysis.yml deleted file mode 100644 index 4c62d96..0000000 --- a/.github/workflows/static-code-analysis.yml +++ /dev/null @@ -1,76 +0,0 @@ -name: "Static code analysis" -on: - push: - branches: [master] - pull_request: - branches: [master] - schedule: - # Everyday at midnight - - cron: '0 0 * * *' -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true -jobs: - static-code-analysis-tests: - runs-on: ubuntu-latest - permissions: - contents: read - steps: - - uses: actions/setup-python@v6 - with: - python-version: '3.x' - - - name: Checkout repository - uses: actions/checkout@v5 - with: - path: sudo-tests - - - name: Setup virtual environment - working-directory: ./sudo-tests/pytest - run: | - sudo apt-get update - - # Install dependencies for python-ldap - sudo apt-get install -y libsasl2-dev python3-dev libldap2-dev libssl-dev libssh-dev - - pip3 install virtualenv - python3 -m venv .venv - source .venv/bin/activate - pip3 install -r ./requirements.txt - pip3 install flake8 pycodestyle isort mypy black - - - name: flake8 - if: always() - working-directory: ./sudo-tests/pytest - run: source .venv/bin/activate && flake8 . - - - name: pycodestyle - if: always() - working-directory: ./sudo-tests/pytest - run: source .venv/bin/activate && pycodestyle . - - - name: isort - if: always() - working-directory: ./sudo-tests/pytest - run: source .venv/bin/activate && isort --check-only . - - - name: black - if: always() - working-directory: ./sudo-tests/pytest - run: source .venv/bin/activate && black --check --diff . - - - name: mypy - if: always() - working-directory: ./sudo-tests/pytest - run: source .venv/bin/activate && mypy --install-types --non-interactive tests - - result: - name: All tests are successful - if: ${{ always() }} - runs-on: ubuntu-latest - needs: [static-code-analysis-tests] - steps: - - name: Fail on failure - if: | - needs.static-code-analysis-tests.result != 'success' - run: exit 1 diff --git a/pytest/pyproject.toml b/pytest/pyproject.toml index b060e7e..04ba358 100644 --- a/pytest/pyproject.toml +++ b/pytest/pyproject.toml @@ -1,3 +1,24 @@ +[tool.ruff] +line-length = 119 +target-version = "py312" +extend-exclude = ["docs"] + +[tool.ruff.lint] +select = [ + "E", # pycodestyle errors + "W", # pycodestyle warnings + "F", # pyflakes + "I", # isort +] +extend-ignore = [] + +[tool.ruff.lint.isort] +required-imports = ["from __future__ import annotations"] + +[tool.ruff.format] +quote-style = "double" +indent-style = "space" + [tool.mypy] exclude = "docs" @@ -16,6 +37,3 @@ add_imports = "from __future__ import annotations" [tool.black] line-length = 119 - -[tool.flake8] -max-line-length = 119 diff --git a/pytest/tests/test_basic.py b/pytest/tests/test_basic.py index 110c0ab..50baf33 100644 --- a/pytest/tests/test_basic.py +++ b/pytest/tests/test_basic.py @@ -6,13 +6,12 @@ from __future__ import annotations +import pytest from sssd_test_framework.roles.ad import AD from sssd_test_framework.roles.client import Client from sssd_test_framework.roles.generic import GenericProvider from sssd_test_framework.topology import KnownTopology -import pytest - def _setup_sudo(client: Client, provider: GenericProvider): if isinstance(provider, Client): @@ -50,12 +49,12 @@ def test_basic__single_user(client: Client, provider: GenericProvider): provider.sudorule("test").add(user=u, host="ALL", command="/bin/ls") client.sssd.restart() - assert client.auth.sudo.run( - u.name, "Secret123", command="/bin/ls /root" - ), f"User {u.name} failed to run sudo with command /bin/ls!" - assert not client.auth.sudo.run( - u2.name, "Secret123", command="/bin/ls /root" - ), f"User {u2.name} was able to run sudo with command /bin/ls!" + assert client.auth.sudo.run(u.name, "Secret123", command="/bin/ls /root"), ( + f"User {u.name} failed to run sudo with command /bin/ls!" + ) + assert not client.auth.sudo.run(u2.name, "Secret123", command="/bin/ls /root"), ( + f"User {u2.name} was able to run sudo with command /bin/ls!" + ) @pytest.mark.importance("high") @@ -82,12 +81,12 @@ def test_basic__single_user_by_uid(client: Client, provider: GenericProvider): provider.sudorule("test").add(user="#10001", host="ALL", command="/bin/ls") client.sssd.restart() - assert client.auth.sudo.run( - u1.name, "Secret123", command="/bin/ls /root" - ), f"User {u1.name} (UID 10001) failed to run sudo with command /bin/ls!" - assert not client.auth.sudo.run( - u2.name, "Secret123", command="/bin/ls /root" - ), f"User {u2.name} (UID 10002) was able to run sudo but should have been denied!" + assert client.auth.sudo.run(u1.name, "Secret123", command="/bin/ls /root"), ( + f"User {u1.name} (UID 10001) failed to run sudo with command /bin/ls!" + ) + assert not client.auth.sudo.run(u2.name, "Secret123", command="/bin/ls /root"), ( + f"User {u2.name} (UID 10002) was able to run sudo but should have been denied!" + ) @pytest.mark.importance("critical") @@ -118,15 +117,15 @@ def test_basic__multiple_users(client: Client, provider: GenericProvider): u3 = provider.user("user-deny").add() provider.sudorule("userlist").add(user=[u1, u2], host="ALL", command="/bin/ls") client.sssd.restart() - assert client.auth.sudo.run( - u1.name, "Secret123", command="/bin/ls /root" - ), f"User {u1.name} failed to run sudo with command /bin/ls!" - assert client.auth.sudo.run( - u2.name, "Secret123", command="/bin/ls /root" - ), f"User {u2.name} failed to run sudo with command /bin/ls!" - assert not client.auth.sudo.run( - u3.name, "Secret123", command="/bin/ls /root" - ), f"User {u3.name} was able to run sudo with command /bin/ls!" + assert client.auth.sudo.run(u1.name, "Secret123", command="/bin/ls /root"), ( + f"User {u1.name} failed to run sudo with command /bin/ls!" + ) + assert client.auth.sudo.run(u2.name, "Secret123", command="/bin/ls /root"), ( + f"User {u2.name} failed to run sudo with command /bin/ls!" + ) + assert not client.auth.sudo.run(u3.name, "Secret123", command="/bin/ls /root"), ( + f"User {u3.name} was able to run sudo with command /bin/ls!" + ) @pytest.mark.importance("critical") @@ -163,12 +162,12 @@ def test_basic__single_group(client: Client, provider: GenericProvider): if isinstance(provider, AD): client.tools.id(u.name) - assert client.auth.sudo.list( - u.name, "Secret123", expected=["(root) /bin/ls"] - ), f"User {u.name} has not /bin/ls in allowed commands!" - assert client.auth.sudo.run( - u.name, "Secret123", command="/bin/ls" - ), f"User {u.name} failed to run sudo with command /bin/ls!" + assert client.auth.sudo.list(u.name, "Secret123", expected=["(root) /bin/ls"]), ( + f"User {u.name} has not /bin/ls in allowed commands!" + ) + assert client.auth.sudo.run(u.name, "Secret123", command="/bin/ls"), ( + f"User {u.name} failed to run sudo with command /bin/ls!" + ) @pytest.mark.importance("high") @@ -200,12 +199,12 @@ def test_basic__single_group_by_gid(client: Client, provider: GenericProvider): client.tools.id(u.name) client.tools.id(u_deny.name) - assert client.auth.sudo.run( - u.name, "Secret123", command="/bin/ls /root" - ), f"User {u.name} (member of group GID 20001) failed to run sudo with command /bin/ls!" - assert not client.auth.sudo.run( - u_deny.name, "Secret123", command="/bin/ls /root" - ), f"User {u_deny.name} was able to run sudo but should have been denied!" + assert client.auth.sudo.run(u.name, "Secret123", command="/bin/ls /root"), ( + f"User {u.name} (member of group GID 20001) failed to run sudo with command /bin/ls!" + ) + assert not client.auth.sudo.run(u_deny.name, "Secret123", command="/bin/ls /root"), ( + f"User {u_deny.name} was able to run sudo but should have been denied!" + ) @pytest.mark.importance("high") @@ -238,12 +237,12 @@ def test_basic__nonposix_group(client: Client, provider: GenericProvider): client.tools.id(u.name) client.tools.id(u_deny.name) - assert client.auth.sudo.run( - u.name, "Secret123", command="/bin/ls /root" - ), f"User {u.name} (member of non-POSIX group) failed to run sudo with command /bin/ls!" - assert not client.auth.sudo.run( - u_deny.name, "Secret123", command="/bin/ls /root" - ), f"User {u_deny.name} was able to run sudo but should have been denied!" + assert client.auth.sudo.run(u.name, "Secret123", command="/bin/ls /root"), ( + f"User {u.name} (member of non-POSIX group) failed to run sudo with command /bin/ls!" + ) + assert not client.auth.sudo.run(u_deny.name, "Secret123", command="/bin/ls /root"), ( + f"User {u_deny.name} was able to run sudo but should have been denied!" + ) @pytest.mark.importance("critical") @@ -283,15 +282,15 @@ def test_basic__multiple_groups(client: Client, provider: GenericProvider): client.tools.id(u2.name) client.tools.id(u3.name) - assert client.auth.sudo.run( - u1.name, "Secret123", command="/bin/ls /root" - ), f"User {u1.name} failed to run sudo with command /bin/ls!" - assert client.auth.sudo.run( - u2.name, "Secret123", command="/bin/ls /root" - ), f"User {u2.name} failed to run sudo with command /bin/ls!" - assert not client.auth.sudo.run( - u3.name, "Secret123", command="/bin/ls /root" - ), f"User {u3.name} was able to run sudo with command /bin/ls but should not have been able to!" + assert client.auth.sudo.run(u1.name, "Secret123", command="/bin/ls /root"), ( + f"User {u1.name} failed to run sudo with command /bin/ls!" + ) + assert client.auth.sudo.run(u2.name, "Secret123", command="/bin/ls /root"), ( + f"User {u2.name} failed to run sudo with command /bin/ls!" + ) + assert not client.auth.sudo.run(u3.name, "Secret123", command="/bin/ls /root"), ( + f"User {u3.name} was able to run sudo with command /bin/ls but should not have been able to!" + ) @pytest.mark.importance("critical") @@ -328,12 +327,12 @@ def test_basic__user_and_group(client: Client, provider: GenericProvider): client.tools.id(u1.name) client.tools.id(u2.name) - assert client.auth.sudo.run( - u1.name, "Secret123", command="/bin/ls /root" - ), f"User {u1.name} failed to run sudo with command /bin/ls!" - assert client.auth.sudo.run( - u2.name, "Secret123", command="/bin/ls /root" - ), f"User {u2.name} failed to run sudo with command /bin/ls!" + assert client.auth.sudo.run(u1.name, "Secret123", command="/bin/ls /root"), ( + f"User {u1.name} failed to run sudo with command /bin/ls!" + ) + assert client.auth.sudo.run(u2.name, "Secret123", command="/bin/ls /root"), ( + f"User {u2.name} failed to run sudo with command /bin/ls!" + ) @pytest.mark.importance("high") @@ -371,15 +370,15 @@ def test_basic__single_netgroup(client: Client, provider: GenericProvider): client.tools.id(u.name) client.tools.id(u_deny.name) - assert client.auth.sudo.list( - u.name, "Secret123", expected=["(root) /bin/ls"] - ), f"User {u.name} has not /bin/ls in allowed commands!" - assert client.auth.sudo.run( - u.name, "Secret123", command="/bin/ls /root" - ), f"User {u.name} failed to run sudo with command /bin/ls!" - assert not client.auth.sudo.run( - u_deny.name, "Secret123", command="/bin/ls /root" - ), f"User {u_deny.name} was able to run sudo but should have been denied!" + assert client.auth.sudo.list(u.name, "Secret123", expected=["(root) /bin/ls"]), ( + f"User {u.name} has not /bin/ls in allowed commands!" + ) + assert client.auth.sudo.run(u.name, "Secret123", command="/bin/ls /root"), ( + f"User {u.name} failed to run sudo with command /bin/ls!" + ) + assert not client.auth.sudo.run(u_deny.name, "Secret123", command="/bin/ls /root"), ( + f"User {u_deny.name} was able to run sudo but should have been denied!" + ) @pytest.mark.importance("critical") @@ -413,12 +412,12 @@ def test_basic__multiple_commands(client: Client, provider: GenericProvider): if isinstance(provider, AD): client.tools.id(u.name) - assert client.auth.sudo.run( - u.name, "Secret123", command="/bin/ls /root" - ), f"User {u.name} failed to run sudo with command /bin/ls!" - assert client.auth.sudo.run( - u.name, "Secret123", command="/bin/df" - ), f"User {u.name} failed to run sudo with command /bin/df!" + assert client.auth.sudo.run(u.name, "Secret123", command="/bin/ls /root"), ( + f"User {u.name} failed to run sudo with command /bin/ls!" + ) + assert client.auth.sudo.run(u.name, "Secret123", command="/bin/df"), ( + f"User {u.name} failed to run sudo with command /bin/df!" + ) @pytest.mark.importance("critical") @@ -451,12 +450,12 @@ def test_basic__excluded_command(client: Client, provider: GenericProvider): if isinstance(provider, AD): client.tools.id(u.name) - assert client.auth.sudo.run( - u.name, "Secret123", command="/bin/ls /root" - ), f"User {u.name} failed to run sudo with command /bin/ls!" - assert not client.auth.sudo.run( - u.name, "Secret123", command="/bin/df" - ), f"User {u.name} was able to run sudo with command /bin/df but should not have been able to!" + assert client.auth.sudo.run(u.name, "Secret123", command="/bin/ls /root"), ( + f"User {u.name} failed to run sudo with command /bin/ls!" + ) + assert not client.auth.sudo.run(u.name, "Secret123", command="/bin/df"), ( + f"User {u.name} was able to run sudo with command /bin/df but should not have been able to!" + ) @pytest.mark.importance("high") @@ -482,12 +481,12 @@ def test_basic__excluded_user(client: Client, provider: GenericProvider): provider.sudorule("test").add(user=["ALL", f"!{u_deny.name}"], host="ALL", command="/bin/ls") client.sssd.restart() - assert client.auth.sudo.run( - u_allow.name, "Secret123", command="/bin/ls /root" - ), f"User {u_allow.name} failed to run sudo with command /bin/ls!" - assert not client.auth.sudo.run( - u_deny.name, "Secret123", command="/bin/ls /root" - ), f"User {u_deny.name} was able to run sudo but should have been denied!" + assert client.auth.sudo.run(u_allow.name, "Secret123", command="/bin/ls /root"), ( + f"User {u_allow.name} failed to run sudo with command /bin/ls!" + ) + assert not client.auth.sudo.run(u_deny.name, "Secret123", command="/bin/ls /root"), ( + f"User {u_deny.name} was able to run sudo but should have been denied!" + ) @pytest.mark.importance("high") @@ -515,12 +514,12 @@ def test_basic__excluded_group(client: Client, provider: GenericProvider): provider.sudorule("test").add(user=["ALL", f"!%{g_deny.name}"], host="ALL", command="/bin/ls") client.sssd.restart() - assert client.auth.sudo.run( - u_allow.name, "Secret123", command="/bin/ls /root" - ), f"User {u_allow.name} failed to run sudo with command /bin/ls!" - assert not client.auth.sudo.run( - u_deny.name, "Secret123", command="/bin/ls /root" - ), f"User {u_deny.name} (in excluded group) was able to run sudo but should have been denied!" + assert client.auth.sudo.run(u_allow.name, "Secret123", command="/bin/ls /root"), ( + f"User {u_allow.name} failed to run sudo with command /bin/ls!" + ) + assert not client.auth.sudo.run(u_deny.name, "Secret123", command="/bin/ls /root"), ( + f"User {u_deny.name} (in excluded group) was able to run sudo but should have been denied!" + ) @pytest.mark.importance("critical") @@ -561,9 +560,9 @@ def test_basic__single_runasuser(client: Client, provider: GenericProvider): assert res.rc == 0, f"User {u1.name} failed to run sudo with command whoami as {u2.name}!" assert u2.name in res.stdout.strip(), f"whoami output mismatch: expected {u2.name!r}, got {res.stdout!r}" - assert ( - client.auth.sudo.run_advanced(u1.name, "Secret123", parameters=["-u", u3.name], command="whoami").rc != 0 - ), f"User {u1.name} was able to run sudo with command whoami as {u3.name} but should not have been able to!" + assert client.auth.sudo.run_advanced(u1.name, "Secret123", parameters=["-u", u3.name], command="whoami").rc != 0, ( + f"User {u1.name} was able to run sudo with command whoami as {u3.name} but should not have been able to!" + ) @pytest.mark.importance("high") @@ -600,9 +599,9 @@ def test_basic__single_runasuser_by_uid(client: Client, provider: GenericProvide assert res.rc == 0, f"User {u1.name} failed to run sudo with command whoami as {u2.name} (UID 10002)!" assert u2.name in res.stdout.strip(), f"whoami output mismatch: expected {u2.name!r}, got {res.stdout!r}" - assert ( - client.auth.sudo.run_advanced(u1.name, "Secret123", parameters=["-u", u3.name], command="whoami").rc != 0 - ), f"User {u1.name} was able to run sudo with command whoami as {u3.name} but should not have been able to!" + assert client.auth.sudo.run_advanced(u1.name, "Secret123", parameters=["-u", u3.name], command="whoami").rc != 0, ( + f"User {u1.name} was able to run sudo with command whoami as {u3.name} but should not have been able to!" + ) @pytest.mark.importance("critical") @@ -677,9 +676,9 @@ def test_basic__single_runasgroup(client: Client, provider: GenericProvider): assert res.rc == 0, f"User {u1.name} failed to run sudo with command id -g as {g1.name}!" assert "20001" in res.stdout.strip(), f"id -g mismatch: expected 20001, got {res.stdout!r}" - assert ( - client.auth.sudo.run_advanced(u1.name, "Secret123", parameters=["-g", g2.name], command="id -g").rc != 0 - ), f"User {u1.name} was able to run sudo with command id -g as {g2.name} but should not have been able to!" + assert client.auth.sudo.run_advanced(u1.name, "Secret123", parameters=["-g", g2.name], command="id -g").rc != 0, ( + f"User {u1.name} was able to run sudo with command id -g as {g2.name} but should not have been able to!" + ) @pytest.mark.importance("high") @@ -717,9 +716,9 @@ def test_basic__single_runasgroup_by_gid(client: Client, provider: GenericProvid assert res.rc == 0, f"User {u1.name} failed to run sudo with command id -g as {g1.name} (GID 20001)!" assert "20001" in res.stdout.strip(), f"id -g mismatch: expected 20001, got {res.stdout!r}" - assert ( - client.auth.sudo.run_advanced(u1.name, "Secret123", parameters=["-g", g2.name], command="id -g").rc != 0 - ), f"User {u1.name} was able to run sudo with command id -g as {g2.name} but should not have been able to!" + assert client.auth.sudo.run_advanced(u1.name, "Secret123", parameters=["-g", g2.name], command="id -g").rc != 0, ( + f"User {u1.name} was able to run sudo with command id -g as {g2.name} but should not have been able to!" + ) @pytest.mark.importance("critical") @@ -758,9 +757,9 @@ def test_basic__multiple_runasgroup(client: Client, provider: GenericProvider): assert res.rc == 0, f"User {u1.name} failed to run sudo with command id -g as {g2.name}!" assert "20002" in res.stdout.strip(), f"id -g mismatch: expected 20002, got {res.stdout!r}" - assert ( - client.auth.sudo.run_advanced(u1.name, "Secret123", parameters=["-g", g3.name], command="id -g").rc != 0 - ), f"User {u1.name} was able to run sudo with command id -g as {g3.name} but should not have been able to!" + assert client.auth.sudo.run_advanced(u1.name, "Secret123", parameters=["-g", g3.name], command="id -g").rc != 0, ( + f"User {u1.name} was able to run sudo with command id -g as {g3.name} but should not have been able to!" + ) @pytest.mark.importance("critical") @@ -850,9 +849,9 @@ def test_basic__hostname_hostname(client: Client, provider: GenericProvider, nam f"{name}: User {u.name} was unable to run 'sudo /bin/ls /root' " f"that should have been allowed on {allowed_host}." ) - assert not client.auth.sudo.run( - u.name, "Secret123", command="/bin/df" - ), f"{name}: User {u.name} was able to run 'sudo /bin/df' that should have been blocked!" + assert not client.auth.sudo.run(u.name, "Secret123", command="/bin/df"), ( + f"{name}: User {u.name} was able to run 'sudo /bin/df' that should have been blocked!" + ) @pytest.mark.importance("critical") @@ -910,9 +909,9 @@ def test_basic__hostname_ip(client: Client, provider: GenericProvider, name: str f"{name}: User {u.name} was unable to run 'sudo /bin/ls /root' " f"that should have been allowed on {allowed_host}." ) - assert not client.auth.sudo.run( - u.name, "Secret123", command="/bin/df" - ), f"{name}: User {u.name} was able to run 'sudo /bin/df' that should have been blocked!" + assert not client.auth.sudo.run(u.name, "Secret123", command="/bin/df"), ( + f"{name}: User {u.name} was able to run 'sudo /bin/df' that should have been blocked!" + ) @pytest.mark.importance("high") @@ -951,12 +950,12 @@ def test_basic__hostname_excluded(client: Client, provider: GenericProvider, nam provider.sudorule("test2").add(user=u, host=f"ALL,!{other_host}", command="/bin/df") client.sssd.restart() - assert not client.auth.sudo.run( - u.name, "Secret123", command="/bin/ls /root" - ), f"{name}: User {u.name} was able to run 'sudo /bin/ls /root' that should have been blocked!" - assert client.auth.sudo.run( - u.name, "Secret123", command="/bin/df" - ), f"{name}: User {u.name} was unable to run 'sudo /bin/df' that should have been allowed!" + assert not client.auth.sudo.run(u.name, "Secret123", command="/bin/ls /root"), ( + f"{name}: User {u.name} was able to run 'sudo /bin/ls /root' that should have been blocked!" + ) + assert client.auth.sudo.run(u.name, "Secret123", command="/bin/df"), ( + f"{name}: User {u.name} was unable to run 'sudo /bin/df' that should have been allowed!" + ) @pytest.mark.importance("medium") @@ -982,9 +981,9 @@ def test_basic__hostname_localhost(client: Client, provider: GenericProvider, na provider.sudorule("test1").add(user=u, host=name, command="/bin/ls") client.sssd.restart() - assert not client.auth.sudo.run( - u.name, "Secret123", command="/bin/ls /root" - ), f"{name}: User {u.name} was able to run 'sudo /bin/ls /root' that should have been blocked!" + assert not client.auth.sudo.run(u.name, "Secret123", command="/bin/ls /root"), ( + f"{name}: User {u.name} was able to run 'sudo /bin/ls /root' that should have been blocked!" + ) @pytest.mark.importance("critical") @@ -1015,12 +1014,12 @@ def test_basic__tags_nopasswd(client: Client, provider: GenericProvider): provider.sudorule("test2").add(user=u, host="ALL", command="/bin/df") client.sssd.restart() - assert client.auth.sudo.run( - u.name, command="/bin/ls /root" - ), f"User {u.name} was unable to run 'sudo /bin/ls /root' that should have been allowed!" - assert not client.auth.sudo.run( - u.name, command="/bin/df" - ), f"User {u.name} was able to run 'sudo /bin/df' that should have been blocked!" + assert client.auth.sudo.run(u.name, command="/bin/ls /root"), ( + f"User {u.name} was unable to run 'sudo /bin/ls /root' that should have been allowed!" + ) + assert not client.auth.sudo.run(u.name, command="/bin/df"), ( + f"User {u.name} was able to run 'sudo /bin/df' that should have been blocked!" + ) @pytest.mark.importance("critical") @@ -1048,17 +1047,17 @@ def test_basic__user_alias_single_user( u = provider.user("user-1").add() u2 = provider.user("user-2").add() user_alias = client.sudoalias("SUDO_USERS", "user") - user_alias.add([u], order=1) + user_alias.add([u.name], order=1) sudo_rule = provider.sudorule("test") - sudo_rule.add(user=user_alias, host="ALL", command="/bin/ls", order=10) + sudo_rule.add(user="SUDO_USERS", host="ALL", command="/bin/ls", order=10) client.sssd.restart() - assert client.auth.sudo.run( - u.name, "Secret123", command="/bin/ls /root" - ), f"User {u.name} failed sudo via User_Alias!" - assert not client.auth.sudo.run( - u2.name, "Secret123", command="/bin/ls /root" - ), f"User {u2.name} should be denied (not in SUDO_USERS)!" + assert client.auth.sudo.run(u.name, "Secret123", command="/bin/ls /root"), ( + f"User {u.name} failed sudo via User_Alias!" + ) + assert not client.auth.sudo.run(u2.name, "Secret123", command="/bin/ls /root"), ( + f"User {u2.name} should be denied (not in SUDO_USERS)!" + ) @pytest.mark.importance("high") @@ -1087,17 +1086,17 @@ def test_basic__user_alias_multiple_members( u2 = provider.user("user-2").add() u3 = provider.user("user-deny").add() user_alias = client.sudoalias("SUDO_USERS", "user") - user_alias.add([u1, u2], order=1) + user_alias.add([u1.name, u2.name], order=1) sudo_rule = provider.sudorule("test") - sudo_rule.add(user=user_alias, host="ALL", command="/bin/ls", order=10) + sudo_rule.add(user="SUDO_USERS", host="ALL", command="/bin/ls", order=10) client.sssd.restart() - assert client.auth.sudo.run( - u1.name, "Secret123", command="/bin/ls /root" - ), f"User {u1.name} failed sudo (User_Alias)!" - assert client.auth.sudo.run( - u2.name, "Secret123", command="/bin/ls /root" - ), f"User {u2.name} failed sudo (User_Alias)!" + assert client.auth.sudo.run(u1.name, "Secret123", command="/bin/ls /root"), ( + f"User {u1.name} failed sudo (User_Alias)!" + ) + assert client.auth.sudo.run(u2.name, "Secret123", command="/bin/ls /root"), ( + f"User {u2.name} failed sudo (User_Alias)!" + ) assert not client.auth.sudo.run( u3.name, "Secret123", @@ -1128,14 +1127,14 @@ def test_basic__user_alias_with_group_member( u = provider.user("user-1").add() g = provider.group("group-1").add().add_member(u) user_alias = client.sudoalias("SUDO_SUBJECTS", "user") - user_alias.add([g], order=1) + user_alias.add([f"%{g.name}"], order=1) sudo_rule = provider.sudorule("test") - sudo_rule.add(user=user_alias, host="ALL", command="/bin/ls", order=10) + sudo_rule.add(user="SUDO_SUBJECTS", host="ALL", command="/bin/ls", order=10) client.sssd.restart() - assert client.auth.sudo.run( - u.name, "Secret123", command="/bin/ls /root" - ), f"User {u.name} failed sudo (User_Alias + group)!" + assert client.auth.sudo.run(u.name, "Secret123", command="/bin/ls /root"), ( + f"User {u.name} failed sudo (User_Alias + group)!" + ) @pytest.mark.importance("high") @@ -1162,12 +1161,12 @@ def test_basic__command_alias( cmd_alias = client.sudoalias("LSHELP", "command") cmd_alias.add("/bin/ls", order=1) sudo_rule = provider.sudorule("test") - sudo_rule.add(user=u, host="ALL", command=cmd_alias, order=10) + sudo_rule.add(user=u, host="ALL", command="LSHELP", order=10) client.sssd.restart() - assert client.auth.sudo.run( - u.name, "Secret123", command="/bin/ls /root" - ), f"User {u.name} failed sudo via Cmnd_Alias!" + assert client.auth.sudo.run(u.name, "Secret123", command="/bin/ls /root"), ( + f"User {u.name} failed sudo via Cmnd_Alias!" + ) @pytest.mark.importance("high") @@ -1195,12 +1194,12 @@ def test_basic__host_alias( host_alias = client.sudoalias("TRUSTED", "host") host_alias.add([short], order=1) sudo_rule = provider.sudorule("test") - sudo_rule.add(user=u, host=host_alias, command="/bin/ls", order=10) + sudo_rule.add(user=u, host="TRUSTED", command="/bin/ls", order=10) client.sssd.restart() - assert client.auth.sudo.run( - u.name, "Secret123", command="/bin/ls /root" - ), f"User {u.name} failed sudo via Host_Alias!" + assert client.auth.sudo.run(u.name, "Secret123", command="/bin/ls /root"), ( + f"User {u.name} failed sudo via Host_Alias!" + ) @pytest.mark.importance("high") @@ -1229,11 +1228,11 @@ def test_basic__runas_user_alias( u2 = provider.user("user-2").add() u3 = provider.user("user-3").add() runas_alias = client.sudoalias("RUN_AS", "runas") - runas_alias.add([u2], order=1) + runas_alias.add([u2.name], order=1) provider.sudorule("test").add( user=u1, host="ALL", - runasuser=runas_alias, + runasuser="RUN_AS", command="/usr/bin/whoami", order=10, ) diff --git a/pytest/tests/test_misc_issues.py b/pytest/tests/test_misc_issues.py index c230ef4..f5e6a17 100644 --- a/pytest/tests/test_misc_issues.py +++ b/pytest/tests/test_misc_issues.py @@ -6,11 +6,10 @@ from __future__ import annotations +import pytest from sssd_test_framework.roles.client import Client from sssd_test_framework.topology import KnownTopology -import pytest - @pytest.mark.topology(KnownTopology.BareClient) @pytest.mark.ticket(jira=["RHEL-59136", "RHEL-127359", "RHEL-127360"]) @@ -74,15 +73,15 @@ def test__regex_wildcard_in_command(client: Client): client.sudorule("user-1-whoami").add(user=u, command="/usr/bin/whoami", host="ALL") client.sudorule("user-1-regex").add(user=u, command="/usr/bin/d*", host="ALL") client.host.conn.run("cat /etc/sudoers.d/*") - assert client.auth.sudo.run( - u.name, "Secret123", command="/usr/bin/whoami" - ), f"Running whoami as {u.name} using sudo failed!" - assert client.auth.sudo.run( - u.name, "Secret123", command="/usr/bin/df" - ), f"Running df as {u.name} using sudo failed!" - assert not client.auth.sudo.run( - u.name, "Secret123", command="/usr/bin/wc" - ), f"Running wc as {u.name} using sudo passed!" + assert client.auth.sudo.run(u.name, "Secret123", command="/usr/bin/whoami"), ( + f"Running whoami as {u.name} using sudo failed!" + ) + assert client.auth.sudo.run(u.name, "Secret123", command="/usr/bin/df"), ( + f"Running df as {u.name} using sudo failed!" + ) + assert not client.auth.sudo.run(u.name, "Secret123", command="/usr/bin/wc"), ( + f"Running wc as {u.name} using sudo passed!" + ) @pytest.mark.topology(KnownTopology.BareClient) @@ -116,15 +115,15 @@ def test__regex_regex_in_command(client: Client): client.sudorule("user-1-whoami").add(user=u, command="/usr/bin/whoami", host="ALL") client.sudorule("user-1-regex").add(user=u, command="^/usr/bin/d.*$", host="ALL") client.host.conn.run("cat /etc/sudoers.d/*") - assert client.auth.sudo.run( - u.name, "Secret123", command="/usr/bin/whoami" - ), f"Running whoami as {u.name} using sudo failed!" - assert client.auth.sudo.run( - u.name, "Secret123", command="/usr/bin/df" - ), f"Running df as {u.name} using sudo failed!" - assert not client.auth.sudo.run( - u.name, "Secret123", command="/usr/bin/wc" - ), f"Running wc as {u.name} using sudo passed!" + assert client.auth.sudo.run(u.name, "Secret123", command="/usr/bin/whoami"), ( + f"Running whoami as {u.name} using sudo failed!" + ) + assert client.auth.sudo.run(u.name, "Secret123", command="/usr/bin/df"), ( + f"Running df as {u.name} using sudo failed!" + ) + assert not client.auth.sudo.run(u.name, "Secret123", command="/usr/bin/wc"), ( + f"Running wc as {u.name} using sudo passed!" + ) @pytest.mark.topology(KnownTopology.BareClient) @@ -153,9 +152,9 @@ def test__regex_regex_in_command_parameter(client: Client): client.sssd.common.sudo() client.sssd.start() client.sudorule("user-1-regex").add(user=u, command="/bin/ls ^/usr/.*$", host="ALL") - assert client.auth.sudo.run( - u.name, "Secret123", command="/bin/ls /usr/sbin" - ), f"Running ls /usr/sbin as {u.name} using sudo failed!" - assert not client.auth.sudo.run( - u.name, "Secret123", command="/bin/ls /root" - ), f"Running ls /root as {u.name} using sudo passed!" + assert client.auth.sudo.run(u.name, "Secret123", command="/bin/ls /usr/sbin"), ( + f"Running ls /usr/sbin as {u.name} using sudo failed!" + ) + assert not client.auth.sudo.run(u.name, "Secret123", command="/bin/ls /root"), ( + f"Running ls /root as {u.name} using sudo passed!" + ) diff --git a/pytest/tests/test_security.py b/pytest/tests/test_security.py index 730cc49..8f28219 100644 --- a/pytest/tests/test_security.py +++ b/pytest/tests/test_security.py @@ -6,11 +6,11 @@ from __future__ import annotations -from sssd_test_framework.roles.client import Client -from sssd_test_framework.topology import KnownTopology +import time import pytest -import time +from sssd_test_framework.roles.client import Client +from sssd_test_framework.topology import KnownTopology # Records effective uid/gid of the mailer process (see CVE-2026-35535 repro). _FAKE_MAILER = """#!/bin/bash @@ -56,9 +56,7 @@ def test_cve__mailer_escalation(client: Client): client.fs.chmod(path="/tmp/fakemailer", mode="ugo+rx") sudoers = ( - "Defaults mailerpath=/tmp/fakemailer\n" - "Defaults mail_always\n" - f"{username} ALL=(ALL) PASSWD: /usr/bin/whoami\n" + f"Defaults mailerpath=/tmp/fakemailer\nDefaults mail_always\n{username} ALL=(ALL) PASSWD: /usr/bin/whoami\n" ) client.fs.write(mailer_drop_in_path, sudoers) client.fs.chmod(path=mailer_drop_in_path, mode="ugo+r") diff --git a/pytest/tests/test_sudo.py b/pytest/tests/test_sudo.py index 1e75ce6..944fe7d 100644 --- a/pytest/tests/test_sudo.py +++ b/pytest/tests/test_sudo.py @@ -10,13 +10,12 @@ import time from datetime import datetime, timedelta +import pytest from sssd_test_framework.roles.client import Client from sssd_test_framework.roles.generic import GenericProvider from sssd_test_framework.roles.ldap import LDAP from sssd_test_framework.topology import KnownTopology -import pytest - @pytest.mark.importance("high") @pytest.mark.topology(KnownTopology.BareAD) @@ -89,15 +88,15 @@ def test_sudo__case_sensitive_false(client: Client, provider: GenericProvider): client.sssd.domain["case_sensitive"] = "false" client.sssd.start() - assert client.auth.sudo.list( - "user-1", "Secret123", expected=["(root) /bin/ls", "(root) /bin/cat"] - ), "Sudo list failed!" + assert client.auth.sudo.list("user-1", "Secret123", expected=["(root) /bin/ls", "(root) /bin/cat"]), ( + "Sudo list failed!" + ) assert client.auth.sudo.run("user-1", "Secret123", command="/bin/ls /root"), "Sudo command failed!" assert client.auth.sudo.run("user-1", "Secret123", command="/bin/cat /root/test"), "Sudo command failed!" - assert client.auth.sudo.list( - "USER-1", "Secret123", expected=["(root) /bin/ls", "(root) /bin/cat"] - ), "Sudo list failed!" + assert client.auth.sudo.list("USER-1", "Secret123", expected=["(root) /bin/ls", "(root) /bin/cat"]), ( + "Sudo list failed!" + ) assert client.auth.sudo.run("USER-1", "Secret123", command="/bin/ls /root"), "Sudo command failed!" assert client.auth.sudo.run("USER-1", "Secret123", command="/bin/cat /root/test"), "Sudo command failed!"