Write a rootpw line if no root customizations in the blueprint

Anaconda requires the root password to be set or locked, so if there
isn't anything setting it we write out 'rootpw --lock'

Also adds tests for this.

Resolves: rhbz#1626122
This commit is contained in:
Brian C. Lane 2018-10-02 12:33:26 -07:00
parent b35fe9d32a
commit c7b4dce2b6
2 changed files with 39 additions and 1 deletions

View File

@ -120,6 +120,8 @@ def write_ks_root(f, user):
:type f: open file object :type f: open file object
:param user: A blueprint user dictionary :param user: A blueprint user dictionary
:type user: dict :type user: dict
:returns: True if it wrote a rootpw command to the kickstart
:rtype: bool
If the entry contains a ssh key, use sshkey to write it If the entry contains a ssh key, use sshkey to write it
If it contains password, use rootpw to set it If it contains password, use rootpw to set it
@ -127,6 +129,8 @@ def write_ks_root(f, user):
root cannot be used with the user command. So only key and password are supported root cannot be used with the user command. So only key and password are supported
for root. for root.
""" """
wrote_rootpw = False
# ssh key uses the sshkey kickstart command # ssh key uses the sshkey kickstart command
if "key" in user: if "key" in user:
f.write('sshkey --user %s "%s"\n' % (user["name"], user["key"])) f.write('sshkey --user %s "%s"\n' % (user["name"], user["key"]))
@ -135,9 +139,13 @@ def write_ks_root(f, user):
if any(user["password"].startswith(prefix) for prefix in ["$2b$", "$6$", "$5$"]): if any(user["password"].startswith(prefix) for prefix in ["$2b$", "$6$", "$5$"]):
log.debug("Detected pre-crypted password") log.debug("Detected pre-crypted password")
f.write('rootpw --iscrypted "%s"\n' % user["password"]) f.write('rootpw --iscrypted "%s"\n' % user["password"])
wrote_rootpw = True
else: else:
log.debug("Detected plaintext password") log.debug("Detected plaintext password")
f.write('rootpw --plaintext "%s"\n' % user["password"]) f.write('rootpw --plaintext "%s"\n' % user["password"])
wrote_rootpw = True
return wrote_rootpw
def write_ks_user(f, user): def write_ks_user(f, user):
""" Write kickstart user and sshkey entry """ Write kickstart user and sshkey entry
@ -219,6 +227,7 @@ def add_customizations(f, recipe):
:raises: RuntimeError if there was a problem writing to the kickstart :raises: RuntimeError if there was a problem writing to the kickstart
""" """
if "customizations" not in recipe: if "customizations" not in recipe:
f.write('rootpw --lock\n')
return return
customizations = recipe["customizations"] customizations = recipe["customizations"]
@ -236,6 +245,8 @@ def add_customizations(f, recipe):
# Creating a user also creates a group. Make a list of the names for later # Creating a user also creates a group. Make a list of the names for later
user_groups = [] user_groups = []
# kickstart requires a rootpw line
wrote_rootpw = False
if "user" in customizations: if "user" in customizations:
# only name is required, everything else is optional # only name is required, everything else is optional
for user in customizations["user"]: for user in customizations["user"]:
@ -244,7 +255,7 @@ def add_customizations(f, recipe):
# root is special, cannot use normal user command for it # root is special, cannot use normal user command for it
if user["name"] == "root": if user["name"] == "root":
write_ks_root(f, user) wrote_rootpw = write_ks_root(f, user)
continue continue
write_ks_user(f, user) write_ks_user(f, user)
@ -257,6 +268,10 @@ def add_customizations(f, recipe):
else: else:
log.warning("Skipping group %s, already created by user", group["name"]) log.warning("Skipping group %s, already created by user", group["name"])
# Lock the root account if no root user password has been specified
if not wrote_rootpw:
f.write('rootpw --lock\n')
def start_build(cfg, dnflock, gitlock, branch, recipe_name, compose_type, test_mode=0): def start_build(cfg, dnflock, gitlock, branch, recipe_name, compose_type, test_mode=0):
""" Start the build """ Start the build

View File

@ -95,6 +95,7 @@ name = "tester"
KS_USER_ALL = '''sshkey --user tester "A SSH KEY FOR THE USER" KS_USER_ALL = '''sshkey --user tester "A SSH KEY FOR THE USER"
user --name tester --homedir /opt/users/tester/ --iscrypted --password "$6$CHO2$3rN8eviE2t50lmVyBYihTgVRHcaecmeCk31LeOUleVK/R/aeWVHVZDi26zAH.o0ywBKH9Tc0/wm7sW/q39uyd1" --shell /usr/bin/zsh --uid 1013 --gid 4242 --gecos "a test user account" user --name tester --homedir /opt/users/tester/ --iscrypted --password "$6$CHO2$3rN8eviE2t50lmVyBYihTgVRHcaecmeCk31LeOUleVK/R/aeWVHVZDi26zAH.o0ywBKH9Tc0/wm7sW/q39uyd1" --shell /usr/bin/zsh --uid 1013 --gid 4242 --gecos "a test user account"
rootpw --lock
''' '''
# ROOT TESTS # ROOT TESTS
@ -117,9 +118,14 @@ class CustomizationsTestCase(unittest.TestCase):
add_customizations(f, r) add_customizations(f, r)
self.assertTrue(result not in f.getvalue(), f.getvalue()) self.assertTrue(result not in f.getvalue(), f.getvalue())
def test_no_customizations(self):
"""Test not setting any customizations"""
self.assertCustomization(BASE_RECIPE, "rootpw --lock")
def test_set_hostname(self): def test_set_hostname(self):
"""Test setting the hostname""" """Test setting the hostname"""
self.assertCustomization(HOSTNAME, "network --hostname=testhostname") self.assertCustomization(HOSTNAME, "network --hostname=testhostname")
self.assertCustomization(HOSTNAME, "rootpw --lock")
def test_set_sshkey(self): def test_set_sshkey(self):
"""Test setting sshkey without user""" """Test setting sshkey without user"""
@ -128,42 +134,52 @@ class CustomizationsTestCase(unittest.TestCase):
def test_sshkey_only(self): def test_sshkey_only(self):
"""Test adding a sshkey to an existing user account""" """Test adding a sshkey to an existing user account"""
self.assertCustomization(USER + USER_KEY, 'sshkey --user tester "A SSH KEY FOR THE USER"') self.assertCustomization(USER + USER_KEY, 'sshkey --user tester "A SSH KEY FOR THE USER"')
self.assertCustomization(USER + USER_KEY, "rootpw --lock")
def test_create_user(self): def test_create_user(self):
"""Test creating a user with no options""" """Test creating a user with no options"""
self.assertCustomization(USER, "user --name tester") self.assertCustomization(USER, "user --name tester")
self.assertCustomization(USER, "rootpw --lock")
def test_create_user_desc(self): def test_create_user_desc(self):
"""Test creating a user with a description""" """Test creating a user with a description"""
self.assertCustomization(USER + USER_DESC, '--gecos "a test user account"') self.assertCustomization(USER + USER_DESC, '--gecos "a test user account"')
self.assertCustomization(USER + USER_DESC, "rootpw --lock")
def test_create_user_crypt(self): def test_create_user_crypt(self):
"""Test creating a user with a pre-crypted password""" """Test creating a user with a pre-crypted password"""
self.assertCustomization(USER + USER_CRYPT, '--password "$6$CHO2$3r') self.assertCustomization(USER + USER_CRYPT, '--password "$6$CHO2$3r')
self.assertCustomization(USER + USER_CRYPT, "rootpw --lock")
def test_create_user_plain(self): def test_create_user_plain(self):
"""Test creating a user with a plaintext password""" """Test creating a user with a plaintext password"""
self.assertCustomization(USER + USER_PLAIN, '--password "plainpassword"') self.assertCustomization(USER + USER_PLAIN, '--password "plainpassword"')
self.assertCustomization(USER + USER_PLAIN, "rootpw --lock")
def test_create_user_home(self): def test_create_user_home(self):
"""Test creating user with a home directory""" """Test creating user with a home directory"""
self.assertCustomization(USER + USER_HOME, "--homedir /opt/users/tester/") self.assertCustomization(USER + USER_HOME, "--homedir /opt/users/tester/")
self.assertCustomization(USER + USER_HOME, "rootpw --lock")
def test_create_user_shell(self): def test_create_user_shell(self):
"""Test creating user with shell set""" """Test creating user with shell set"""
self.assertCustomization(USER + USER_SHELL, "--shell /usr/bin/zsh") self.assertCustomization(USER + USER_SHELL, "--shell /usr/bin/zsh")
self.assertCustomization(USER + USER_SHELL, "rootpw --lock")
def test_create_user_uid(self): def test_create_user_uid(self):
"""Test creating user with uid set""" """Test creating user with uid set"""
self.assertCustomization(USER + USER_UID, "--uid 1013") self.assertCustomization(USER + USER_UID, "--uid 1013")
self.assertCustomization(USER + USER_UID, "rootpw --lock")
def test_create_user_gid(self): def test_create_user_gid(self):
"""Test creating user with gid set""" """Test creating user with gid set"""
self.assertCustomization(USER + USER_GID, "--gid 4242") self.assertCustomization(USER + USER_GID, "--gid 4242")
self.assertCustomization(USER + USER_GID, "rootpw --lock")
def test_create_user_groups(self): def test_create_user_groups(self):
"""Test creating user with group membership""" """Test creating user with group membership"""
self.assertCustomization(USER + USER_GROUPS, "--groups wheel,users") self.assertCustomization(USER + USER_GROUPS, "--groups wheel,users")
self.assertCustomization(USER + USER_GROUPS, "rootpw --lock")
def test_user_same_group(self): def test_user_same_group(self):
"""Test creating a group with the same name as a user""" """Test creating a group with the same name as a user"""
@ -171,6 +187,7 @@ class CustomizationsTestCase(unittest.TestCase):
# Creating a group with the same name should skip the group creation # Creating a group with the same name should skip the group creation
self.assertCustomization(USER_GROUP, "user --name tester") self.assertCustomization(USER_GROUP, "user --name tester")
self.assertNotCustomization(USER_GROUP, "group --name tester") self.assertNotCustomization(USER_GROUP, "group --name tester")
self.assertCustomization(USER_GROUP, "rootpw --lock")
def test_create_user_all(self): def test_create_user_all(self):
"""Test creating user with all settings""" """Test creating user with all settings"""
@ -182,21 +199,27 @@ class CustomizationsTestCase(unittest.TestCase):
def test_create_group(self): def test_create_group(self):
"""Test creating group without gid set""" """Test creating group without gid set"""
self.assertCustomization(GROUP, "group --name testgroup") self.assertCustomization(GROUP, "group --name testgroup")
self.assertCustomization(GROUP, "rootpw --lock")
def test_create_group_gid(self): def test_create_group_gid(self):
"""Test creating group with gid set""" """Test creating group with gid set"""
self.assertCustomization(GROUP_GID, "group --name testgroup --gid 1011") self.assertCustomization(GROUP_GID, "group --name testgroup --gid 1011")
self.assertCustomization(GROUP_GID, "rootpw --lock")
def test_root_crypt(self): def test_root_crypt(self):
self.assertCustomization(ROOT_CRYPT, 'rootpw --iscrypted "$6$CHO2$3r') self.assertCustomization(ROOT_CRYPT, 'rootpw --iscrypted "$6$CHO2$3r')
self.assertNotCustomization(ROOT_CRYPT, "rootpw --lock")
def test_root_plain(self): def test_root_plain(self):
self.assertCustomization(ROOT_PLAIN, 'rootpw --plaintext "plainpassword"') self.assertCustomization(ROOT_PLAIN, 'rootpw --plaintext "plainpassword"')
self.assertNotCustomization(ROOT_PLAIN, "rootpw --lock")
def test_root_crypt_key(self): def test_root_crypt_key(self):
self.assertCustomization(ROOT_CRYPT_KEY, 'rootpw --iscrypted "$6$CHO2$3r') self.assertCustomization(ROOT_CRYPT_KEY, 'rootpw --iscrypted "$6$CHO2$3r')
self.assertCustomization(ROOT_CRYPT_KEY, 'sshkey --user root "A SSH KEY FOR THE USER"') self.assertCustomization(ROOT_CRYPT_KEY, 'sshkey --user root "A SSH KEY FOR THE USER"')
self.assertNotCustomization(ROOT_CRYPT_KEY, "rootpw --lock")
def test_root_plain_key(self): def test_root_plain_key(self):
self.assertCustomization(ROOT_PLAIN_KEY, 'rootpw --plaintext "plainpassword"') self.assertCustomization(ROOT_PLAIN_KEY, 'rootpw --plaintext "plainpassword"')
self.assertCustomization(ROOT_PLAIN_KEY, 'sshkey --user root "A SSH KEY FOR THE USER"') self.assertCustomization(ROOT_PLAIN_KEY, 'sshkey --user root "A SSH KEY FOR THE USER"')
self.assertNotCustomization(ROOT_PLAIN_KEY, "rootpw --lock")