user: Fix homedir permissions when UMASK is unset in /etc/login.defs

When a user doesn't exist and user module is used to create the user and the
homedir, adduser is called which parses HOME_MODE from /etc/login.defs, and when
not set calculates the mode from UMASK from the same file.

When a user already exists without homedir, and the user module is used to add a
home dir, it incorrectly ignores HOME_MODE, resulting in a world-readable home
dir when UMASK is not set. This is for example the case in Debian trixie and
later, and likely Ubuntu 25.04 and later.


Signed-off-by: Lee Garrett <lgarrett@rocketjump.eu>
Co-authored-by: Brian Coca <bcoca@users.noreply.github.com>
Co-authored-by: Abhijeet Kasurde <akasurde@redhat.com>
pull/84561/head
Lee Garrett 11 months ago committed by GitHub
parent 5623a386c1
commit 3030c79331
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,3 @@
---
bugfixes:
- user - Use higher precedence HOME_MODE as UMASK for path provided (https://github.com/ansible/ansible/pull/84482).

@ -1376,16 +1376,24 @@ class User(object):
self.module.exit_json(failed=True, msg="%s" % to_native(e))
# get umask from /etc/login.defs and set correct home mode
if os.path.exists(self.LOGIN_DEFS):
with open(self.LOGIN_DEFS, 'r') as f:
for line in f:
m = re.match(r'^UMASK\s+(\d+)$', line)
if m:
umask = int(m.group(1), 8)
# fallback if neither HOME_MODE nor UMASK are set;
# follow behaviour of useradd initializing UMASK = 022
mode = 0o755
with open(self.LOGIN_DEFS, 'r') as fh:
for line in fh:
# HOME_MODE has higher precedence as UMASK
match = re.match(r'^HOME_MODE\s+(\d+)$', line)
if match:
mode = int(match.group(1), 8)
break # higher precedence
match = re.match(r'^UMASK\s+(\d+)$', line)
if match:
umask = int(match.group(1), 8)
mode = 0o777 & ~umask
try:
os.chmod(path, mode)
except OSError as e:
self.module.exit_json(failed=True, msg="%s" % to_native(e))
try:
os.chmod(path, mode)
except OSError as e:
self.module.exit_json(failed=True, msg=to_native(e))
def chown_homedir(self, uid, gid, path):
try:

@ -35,12 +35,17 @@
import os
try:
for line in open('/etc/login.defs').readlines():
m = re.match(r'^HOME_MODE\s+(\d+)$', line)
if m:
mode = oct(int(m.group(1), 8))
break
m = re.match(r'^UMASK\s+(\d+)$', line)
if m:
umask = int(m.group(1), 8)
mode = oct(0o777 & ~umask)
except:
umask = os.umask(0)
mode = oct(0o777 & ~umask)
mode = oct(0o777 & ~umask)
print(str(mode).replace('o', ''))
args:
executable: "{{ ansible_python_interpreter }}"

Loading…
Cancel
Save