mirror of
https://github.com/saltstack/salt.git
synced 2025-04-17 10:10:20 +00:00
Handles FileNotFoundError exception in shadow.info
Musl libc getspnam implementation returns ENOENT when user is not found Changing the linux_shadow.info to deal with FileNotFoundError, allowing the user.present state to work in musl based systems, like the Alpine Linux.
This commit is contained in:
parent
1f74210c03
commit
0f777f5221
3 changed files with 56 additions and 11 deletions
1
changelog/50979.fixed
Normal file
1
changelog/50979.fixed
Normal file
|
@ -0,0 +1 @@
|
|||
Allow user.present to work on Alpine Linux by fixing linux_shadow.info
|
|
@ -1,4 +1,3 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Manage the shadow file on Linux systems
|
||||
|
||||
|
@ -8,21 +7,16 @@ Manage the shadow file on Linux systems
|
|||
*'shadow.info' is not available*), see :ref:`here
|
||||
<module-provider-override>`.
|
||||
"""
|
||||
from __future__ import absolute_import, print_function, unicode_literals
|
||||
|
||||
import datetime
|
||||
import functools
|
||||
import logging
|
||||
|
||||
# Import python libs
|
||||
import os
|
||||
|
||||
# Import salt libs
|
||||
import salt.utils.data
|
||||
import salt.utils.files
|
||||
import salt.utils.stringutils
|
||||
from salt.exceptions import CommandExecutionError
|
||||
from salt.ext import six
|
||||
from salt.ext.six.moves import range
|
||||
|
||||
try:
|
||||
|
@ -93,7 +87,7 @@ def info(name, root=None):
|
|||
"inact": data.sp_inact,
|
||||
"expire": data.sp_expire,
|
||||
}
|
||||
except KeyError:
|
||||
except (KeyError, FileNotFoundError):
|
||||
return {
|
||||
"name": "",
|
||||
"passwd": "",
|
||||
|
@ -385,7 +379,7 @@ def set_password(name, password, use_usermod=False, root=None):
|
|||
# ALT Linux uses tcb to store password hashes. More information found
|
||||
# in manpage (http://docs.altlinux.org/manpages/tcb.5.html)
|
||||
if __grains__["os"] == "ALT":
|
||||
s_file = "/etc/tcb/{0}/shadow".format(name)
|
||||
s_file = "/etc/tcb/{}/shadow".format(name)
|
||||
else:
|
||||
s_file = "/etc/shadow"
|
||||
if root:
|
||||
|
@ -396,9 +390,7 @@ def set_password(name, password, use_usermod=False, root=None):
|
|||
return ret
|
||||
lines = []
|
||||
user_found = False
|
||||
lstchg = six.text_type(
|
||||
(datetime.datetime.today() - datetime.datetime(1970, 1, 1)).days
|
||||
)
|
||||
lstchg = str((datetime.datetime.today() - datetime.datetime(1970, 1, 1)).days)
|
||||
with salt.utils.files.fopen(s_file, "rb") as fp_:
|
||||
for line in fp_:
|
||||
line = salt.utils.stringutils.to_unicode(line)
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
:codeauthor: Erik Johnson <erik@saltstack.com>
|
||||
"""
|
||||
|
||||
import spwd
|
||||
import textwrap
|
||||
|
||||
import pytest
|
||||
|
@ -143,6 +144,57 @@ class LinuxShadowTest(TestCase, LoaderModuleMockMixin):
|
|||
# Make sure we wrote the correct info
|
||||
assert filehandles[1].write_calls[0].split(":")[:2] == [user, password]
|
||||
|
||||
def test_info(self):
|
||||
"""
|
||||
Test if info shows the correct user information
|
||||
"""
|
||||
|
||||
# First test is with a succesful call
|
||||
expected_result = [
|
||||
("expire", -1),
|
||||
("inact", -1),
|
||||
("lstchg", 31337),
|
||||
("max", 99999),
|
||||
("min", 0),
|
||||
("name", "foo"),
|
||||
("passwd", _HASHES["sha512"]["pw_hash"]),
|
||||
("warn", 7),
|
||||
]
|
||||
getspnam_return = spwd.struct_spwd(
|
||||
["foo", _HASHES["sha512"]["pw_hash"], 31337, 0, 99999, 7, -1, -1, -1]
|
||||
)
|
||||
with patch("spwd.getspnam", return_value=getspnam_return):
|
||||
result = shadow.info("foo")
|
||||
self.assertEqual(
|
||||
expected_result, sorted(result.items(), key=lambda x: x[0])
|
||||
)
|
||||
|
||||
# The next two is for a non-existent user
|
||||
expected_result = [
|
||||
("expire", ""),
|
||||
("inact", ""),
|
||||
("lstchg", ""),
|
||||
("max", ""),
|
||||
("min", ""),
|
||||
("name", ""),
|
||||
("passwd", ""),
|
||||
("warn", ""),
|
||||
]
|
||||
# We get KeyError exception for non-existent users in glibc based systems
|
||||
getspnam_return = KeyError
|
||||
with patch("spwd.getspnam", side_effect=getspnam_return):
|
||||
result = shadow.info("foo")
|
||||
self.assertEqual(
|
||||
expected_result, sorted(result.items(), key=lambda x: x[0])
|
||||
)
|
||||
# And FileNotFoundError in musl based systems
|
||||
getspnam_return = FileNotFoundError
|
||||
with patch("spwd.getspnam", side_effect=getspnam_return):
|
||||
result = shadow.info("foo")
|
||||
self.assertEqual(
|
||||
expected_result, sorted(result.items(), key=lambda x: x[0])
|
||||
)
|
||||
|
||||
@pytest.mark.skip_if_not_root
|
||||
def test_list_users(self):
|
||||
"""
|
||||
|
|
Loading…
Add table
Reference in a new issue