Skip to content

Commit

Permalink
Support sudoers in the "usr merge" location
Browse files Browse the repository at this point in the history
With the usr merge effort many configuration files are moving from /etc to
/usr/etc clearing the way for the /etc directory to be a space managed
by the system administrator and the /usr/etc space used by the distribution
vendor. Support the /usr/etc/sudoers location when managing the sudoers file.
  • Loading branch information
rjschwei committed Apr 8, 2024
1 parent 6d5978b commit b3a518f
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 8 deletions.
25 changes: 17 additions & 8 deletions cloudinit/distros/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1006,14 +1006,20 @@ def write_doas_rules(self, user, rules, doas_file=None):
)
raise e

def ensure_sudo_dir(self, path, sudo_base="/etc/sudoers"):
def ensure_sudo_dir(
self, path, sudo_base=("/etc/sudoers","/usr/etc/sudoers")):
# Ensure the dir is included and that
# it actually exists as a directory
sudoers_contents = ""
base_exists = False
if os.path.exists(sudo_base):
sudoers_contents = util.load_text_file(sudo_base)
base_exists = True
admin_sudo_base = "/etc/sudoers"
if not isinstance(sudo_base, (list, tuple)):
sudo_base = [sudo_base]
for sudoers_base in sudo_base:
if os.path.exists(sudoers_base):
sudoers_contents = util.load_text_file(sudoers_base)
base_exists = True
break
found_include = False
for line in sudoers_contents.splitlines():
line = line.strip()
Expand All @@ -1039,19 +1045,22 @@ def ensure_sudo_dir(self, path, sudo_base="/etc/sudoers"):
"",
]
sudoers_contents = "\n".join(lines)
util.write_file(sudo_base, sudoers_contents, 0o440)
util.write_file(admin_sudo_base, sudoers_contents, 0o440)
else:
if sudoers_base != admin_sudo_base:
util.write_file(
admin_sudo_base, sudoers_contents, 0o440)
lines = [
"",
util.make_header(base="added"),
"#includedir %s" % (path),
"",
]
sudoers_contents = "\n".join(lines)
util.append_file(sudo_base, sudoers_contents)
LOG.debug("Added '#includedir %s' to %s", path, sudo_base)
util.append_file(admin_sudo_base, sudoers_contents)
LOG.debug("Added '#includedir %s' to %s", path, admin_sudo_base)
except IOError as e:
util.logexc(LOG, "Failed to write %s", sudo_base)
util.logexc(LOG, "Failed to write %s", admin_sudo_base)
raise e
util.ensure_dir(path, 0o750)

Expand Down
26 changes: 26 additions & 0 deletions tests/unittests/distros/test__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,32 @@ def test_sudoers_ensure_append(self):
self.assertIn("josh", contents)
self.assertEqual(2, contents.count("josh"))

def test_sudoers_ensure_append_sudoer_file(self):
cls = distros.fetch("ubuntu")
d = cls("ubuntu", {}, None)
self.patchOS(self.tmp)
self.patchUtils(self.tmp)
util.write_file("/etc/sudoers", "josh, josh\n")
d.ensure_sudo_dir("/b", "/etc/sudoers")
contents = util.load_text_file("/etc/sudoers")
self.assertIn("includedir /b", contents)
self.assertTrue(os.path.isdir("/b"))
self.assertIn("josh", contents)
self.assertEqual(2, contents.count("josh"))

def test_usr_sudoers_ensure_append(self):
cls = distros.fetch("ubuntu")
d = cls("ubuntu", {}, None)
self.patchOS(self.tmp)
self.patchUtils(self.tmp)
util.write_file("/usr/etc/sudoers", "josh, josh\n")
d.ensure_sudo_dir("/b")
contents = util.load_text_file("/etc/sudoers")
self.assertIn("includedir /b", contents)
self.assertTrue(os.path.isdir("/b"))
self.assertIn("josh", contents)
self.assertEqual(2, contents.count("josh"))

def test_sudoers_ensure_only_one_includedir(self):
cls = distros.fetch("ubuntu")
d = cls("ubuntu", {}, None)
Expand Down

0 comments on commit b3a518f

Please sign in to comment.