Skip to content

Commit 1aa42d1

Browse files
committed
Set Authselect agruments after run in Security module
Ensure authselect arguments are always persisted in the generated kickstart (KS) file, including when configuration is performed manually. By only running the fingerprint configuration when no KS authselect options are present, we avoid overriding user-supplied settings and keep the output KS consistent and reproducible. Resolves: RHEL-85175
1 parent 38116f3 commit 1aa42d1

File tree

3 files changed

+85
-45
lines changed

3 files changed

+85
-45
lines changed

pyanaconda/modules/security/installation.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
from pyanaconda.core.configuration.anaconda import conf
2525
from pyanaconda.core.constants import PAYLOAD_TYPE_DNF
2626
from pyanaconda.core.path import join_paths, make_directories
27+
from pyanaconda.modules.common.constants.services import SECURITY
2728
from pyanaconda.modules.common.errors.installation import SecurityInstallationError
2829
from pyanaconda.modules.common.task import Task
2930
from pyanaconda.modules.security.constants import SELinuxMode
@@ -443,6 +444,10 @@ def run(self):
443444
required=False
444445
)
445446

447+
security_proxy = SECURITY.get_proxy()
448+
security_proxy.Authselect = AUTHSELECT_ARGS
449+
log.debug("Authselect kickstart set to: %s", AUTHSELECT_ARGS)
450+
446451

447452
class ConfigureAuthselectTask(Task):
448453
"""Installation task for Authselect configuration."""

pyanaconda/modules/security/security.py

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@
3333
from pyanaconda.modules.security.certificates import CertificatesModule
3434
from pyanaconda.modules.security.constants import SELinuxMode
3535
from pyanaconda.modules.security.installation import (
36-
AUTHSELECT_ARGS,
3736
ConfigureAuthselectTask,
3837
ConfigureFingerprintAuthTask,
3938
ConfigureFIPSTask,
@@ -113,8 +112,6 @@ def setup_kickstart(self, data):
113112

114113
if self.authselect:
115114
data.authselect.authselect = " ".join(self.authselect)
116-
elif self.fingerprint_auth_enabled:
117-
data.authselect.authselect = " ".join(AUTHSELECT_ARGS)
118115

119116
if self.realm.name:
120117
data.realm.join_realm = self.realm.name
@@ -287,17 +284,32 @@ def install_with_tasks(self):
287284
288285
:returns: list of installation tasks
289286
"""
290-
return [
291-
ConfigureSELinuxTask(
292-
sysroot=conf.target.system_root,
293-
selinux_mode=self.selinux
294-
),
295-
ConfigureFingerprintAuthTask(
296-
sysroot=conf.target.system_root,
297-
fingerprint_auth_enabled=self.fingerprint_auth_enabled
298-
),
299-
ConfigureAuthselectTask(
300-
sysroot=conf.target.system_root,
301-
authselect_options=self.authselect
287+
tasks = []
288+
289+
# 1) SELinux first
290+
tasks.append(
291+
ConfigureSELinuxTask(sysroot=conf.target.system_root, selinux_mode=self.selinux)
292+
)
293+
294+
# 2) Fingerprint vs Authselect
295+
if self.fingerprint_auth_enabled and not self.authselect:
296+
log.debug("No KS authselect args; enqueue ConfigureFingerprintAuthTask.")
297+
tasks.append(
298+
ConfigureFingerprintAuthTask(
299+
sysroot=conf.target.system_root,
300+
fingerprint_auth_enabled=self.fingerprint_auth_enabled,
301+
)
302302
)
303-
]
303+
elif self.authselect:
304+
log.debug(
305+
"KS authselect present %s; enqueue ConfigureAuthselectTask.", self.authselect
306+
)
307+
tasks.append(
308+
ConfigureAuthselectTask(
309+
sysroot=conf.target.system_root, authselect_options=self.authselect
310+
)
311+
)
312+
else:
313+
log.debug("No fingerprint (without args) and no KS authselect; nothing to configure.")
314+
315+
return tasks

tests/unit_tests/pyanaconda_tests/modules/security/test_module_security.py

Lines changed: 52 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import unittest
2323
from contextlib import contextmanager
2424
from textwrap import dedent
25+
from types import SimpleNamespace
2526
from unittest.mock import patch
2627

2728
import pytest
@@ -36,6 +37,7 @@
3637
from pyanaconda.modules.common.structures.requirement import Requirement
3738
from pyanaconda.modules.security.constants import SELinuxMode
3839
from pyanaconda.modules.security.installation import (
40+
AUTHSELECT_ARGS,
3941
AUTHSELECT_TOOL_PATH,
4042
PAM_SO_64_PATH,
4143
PAM_SO_PATH,
@@ -159,6 +161,22 @@ def test_authselect_kickstart(self):
159161
"""
160162
self._test_kickstart(ks_in, ks_out)
161163

164+
def test_kickstart_contains_authselect_when_module_property_is_set(self):
165+
self.security_interface.Authselect = [
166+
"select",
167+
"sssd",
168+
"with-fingerprint",
169+
"with-silent-lastlog",
170+
"--force",
171+
]
172+
173+
ks_in = ""
174+
ks_out = """
175+
# System authorization information
176+
authselect select sssd with-fingerprint with-silent-lastlog --force
177+
"""
178+
self._test_kickstart(ks_in, ks_out)
179+
162180
def test_realm_kickstart(self):
163181
"""Test the realm command."""
164182
ks_in = """
@@ -232,17 +250,6 @@ def test_certificates_kickstart(self):
232250
"""
233251
self._test_kickstart(ks_in, ks_out)
234252

235-
def test_kickstart_authselect_merges_with_fingerprint(self):
236-
self.security_interface.FingerprintAuthEnabled = True
237-
238-
ks_in = ""
239-
ks_out = """
240-
# System authorization information
241-
authselect enable-feature with-fingerprint
242-
"""
243-
244-
self._test_kickstart(ks_in, ks_out)
245-
246253
@patch_dbus_publish_object
247254
def test_realm_discover_default(self, publisher):
248255
"""Test module in default state with realm discover task."""
@@ -270,21 +277,13 @@ def test_install_with_tasks_default(self, publisher):
270277
"""Test InstallWithTasks."""
271278
task_classes = [
272279
ConfigureSELinuxTask,
273-
ConfigureFingerprintAuthTask,
274-
ConfigureAuthselectTask,
275280
]
276281
task_paths = self.security_interface.InstallWithTasks()
277282
task_objs = check_task_creation_list(task_paths, publisher, task_classes)
278283

279284
# ConfigureSELinuxTask
280285
obj = task_objs[0]
281286
assert obj.implementation._selinux_mode == SELinuxMode.DEFAULT
282-
# ConfigureFingerprintAuthTask
283-
obj = task_objs[1]
284-
assert obj.implementation._fingerprint_auth_enabled is False
285-
# ConfigureAuthselectTask
286-
obj = task_objs[2]
287-
assert obj.implementation._authselect_options == []
288287

289288
@patch_dbus_publish_object
290289
def test_realm_join_default(self, publisher):
@@ -312,9 +311,9 @@ def test_install_with_tasks_configured(self, publisher):
312311
self.security_interface.Authselect = authselect
313312
self.security_interface.FingerprintAuthEnabled = fingerprint
314313

314+
# We have ks args => no fingerprint task
315315
task_classes = [
316316
ConfigureSELinuxTask,
317-
ConfigureFingerprintAuthTask,
318317
ConfigureAuthselectTask,
319318
]
320319
task_paths = self.security_interface.InstallWithTasks()
@@ -323,13 +322,30 @@ def test_install_with_tasks_configured(self, publisher):
323322
# ConfigureSELinuxTask
324323
obj = task_objs[0]
325324
assert obj.implementation._selinux_mode == SELinuxMode.PERMISSIVE
326-
# ConfigureFingerprintAuthTask
327-
obj = task_objs[1]
328-
assert obj.implementation._fingerprint_auth_enabled == fingerprint
329325
# ConfigureAuthselectTask
330-
obj = task_objs[2]
326+
obj = task_objs[1]
331327
assert obj.implementation._authselect_options == authselect
332328

329+
@patch_dbus_publish_object
330+
def test_install_with_tasks_fingerprint_only(self, publisher):
331+
"""When fingerprint is enabled and KS authselect is empty, enqueue fingerprint task."""
332+
self.security_interface.FingerprintAuthEnabled = True
333+
self.security_interface.Authselect = []
334+
335+
task_classes = [
336+
ConfigureSELinuxTask,
337+
ConfigureFingerprintAuthTask,
338+
]
339+
task_paths = self.security_interface.InstallWithTasks()
340+
task_objs = check_task_creation_list(task_paths, publisher, task_classes)
341+
342+
# ConfigureSELinuxTask
343+
obj = task_objs[0]
344+
assert obj.implementation._selinux_mode == SELinuxMode.DEFAULT
345+
# ConfigureFingerprintAuthTask
346+
obj = task_objs[1]
347+
assert obj.implementation._fingerprint_auth_enabled is True
348+
333349
@patch_dbus_publish_object
334350
def test_realm_join_configured(self, publisher):
335351
"""Test module in configured state with realm join task."""
@@ -888,9 +904,12 @@ def test_realm_join_not_discovered(self, execWithRedirect):
888904
# check if the realm command invocation looks right
889905
execWithRedirect.assert_not_called()
890906

891-
@patch('pyanaconda.core.util.execWithRedirect')
892-
def test_configure_fingerprint_auth_task(self, execWithRedirect):
893-
"""Test the configure fingerprint task."""
907+
@patch("pyanaconda.modules.security.installation.SECURITY.get_proxy")
908+
@patch("pyanaconda.core.util.execWithRedirect")
909+
def test_configure_fingerprint_auth_task(self, execWithRedirect, get_proxy):
910+
proxy = SimpleNamespace(Authselect=[])
911+
get_proxy.return_value = proxy
912+
894913
with tempfile.TemporaryDirectory() as sysroot:
895914

896915
authselect_dir = os.path.normpath(sysroot + os.path.dirname(AUTHSELECT_TOOL_PATH))
@@ -925,6 +944,7 @@ def test_configure_fingerprint_auth_task(self, execWithRedirect):
925944

926945
# Authselect command and pam library are there
927946
execWithRedirect.reset_mock()
947+
proxy.Authselect = []
928948
os.mknod(pam_so_path)
929949
os.mknod(authselect_path)
930950
task = ConfigureFingerprintAuthTask(
@@ -934,14 +954,16 @@ def test_configure_fingerprint_auth_task(self, execWithRedirect):
934954
task.run()
935955
execWithRedirect.assert_called_once_with(
936956
AUTHSELECT_TOOL_PATH,
937-
["enable-feature", "with-fingerprint"],
957+
AUTHSELECT_ARGS,
938958
root=sysroot
939959
)
960+
assert proxy.Authselect == AUTHSELECT_ARGS
940961
os.remove(pam_so_path)
941962
os.remove(authselect_path)
942963

943964
# Authselect command and pam library are there
944965
execWithRedirect.reset_mock()
966+
proxy.Authselect = []
945967
os.mknod(pam_so_64_path)
946968
os.mknod(authselect_path)
947969
task = ConfigureFingerprintAuthTask(
@@ -951,9 +973,10 @@ def test_configure_fingerprint_auth_task(self, execWithRedirect):
951973
task.run()
952974
execWithRedirect.assert_called_once_with(
953975
AUTHSELECT_TOOL_PATH,
954-
["enable-feature", "with-fingerprint"],
976+
AUTHSELECT_ARGS,
955977
root=sysroot
956978
)
979+
assert proxy.Authselect == AUTHSELECT_ARGS
957980
os.remove(pam_so_64_path)
958981
os.remove(authselect_path)
959982

0 commit comments

Comments
 (0)