diff --git a/cobbler/modules/authentication/pam.py b/cobbler/modules/authentication/pam.py index 97ecc02ab0..893422c5ba 100644 --- a/cobbler/modules/authentication/pam.py +++ b/cobbler/modules/authentication/pam.py @@ -114,6 +114,10 @@ class PamConv(Structure): PAM_AUTHENTICATE.restype = c_int PAM_AUTHENTICATE.argtypes = [PamHandle, c_int] +PAM_ACCT_MGMT = LIBPAM.pam_acct_mgmt +PAM_ACCT_MGMT.restype = c_int +PAM_ACCT_MGMT.argtypes = [PamHandle, c_int] + def authenticate(api_handle, username: str, password: str) -> bool: """ @@ -157,4 +161,8 @@ def my_conv(n_messages, messages, p_response, app_data): return False retval = PAM_AUTHENTICATE(handle, 0) + + if retval == 0: + retval = PAM_ACCT_MGMT(handle, 0) + return retval == 0 diff --git a/tests/special_cases/security_test.py b/tests/special_cases/security_test.py index cbc4bfa2e5..74ace127b9 100644 --- a/tests/special_cases/security_test.py +++ b/tests/special_cases/security_test.py @@ -3,12 +3,17 @@ """ # SPDX-License-Identifier: GPL-2.0-or-later import base64 +import crypt +import logging import os +import subprocess import xmlrpc.client import pytest +from cobbler.api import CobblerAPI from cobbler.utils import get_shared_secret +from cobbler.modules.authentication import pam # ==================== Start tnpconsultants ==================== @@ -110,3 +115,26 @@ def test_arbitrary_file_write_1(setup_profile, try_connect): assert result is False # ==================== END tnpconsultants ==================== + +# ==================== START ysf ==================== + +# SPDX-FileCopyrightText: 2022 ysf + + +def test_pam_login_with_expired_user(): + # Arrange + test_api = CobblerAPI() + test_username = "expired_user" + test_password = "password" + # create pam testuser + subprocess.run(["useradd", "-p", crypt.crypt(test_password), test_username]) + # change user to be expired + subprocess.run(["chage", "-E0", test_username]) + + # Act - Try login + result = pam.authenticate(test_api, test_username, test_password) + + # Assert - Login failed + assert not result + +# ==================== END ysf ====================