diff --git a/changelogs/fragments/fix_create_home.yml b/changelogs/fragments/fix_create_home.yml deleted file mode 100644 index 46c774645a1..00000000000 --- a/changelogs/fragments/fix_create_home.yml +++ /dev/null @@ -1,4 +0,0 @@ -bugfixes: - - >- - user - properly create home path on Linux when ``local: yes`` and parent directories - specified in ``home`` do not exist (https://github.com/ansible/ansible/pull/71952/) diff --git a/lib/ansible/modules/user.py b/lib/ansible/modules/user.py index f19cb83d5d9..674d74d7a29 100644 --- a/lib/ansible/modules/user.py +++ b/lib/ansible/modules/user.py @@ -686,8 +686,13 @@ class User(object): cmd.append(self.comment) if self.home is not None: + # If the specified path to the user home contains parent directories that + # do not exist and create_home is True first create the parent directory + # since useradd cannot create it. if self.create_home: - self.create_homedir(self.home) + parent = os.path.dirname(self.home) + if not os.path.isdir(parent): + self.create_homedir(self.home) cmd.append('-d') cmd.append(self.home) @@ -709,7 +714,19 @@ class User(object): else: cmd.append(self.password) - cmd.append('-M') + if self.create_home: + if not self.local: + cmd.append('-m') + + if self.skeleton is not None: + cmd.append('-k') + cmd.append(self.skeleton) + + if self.umask is not None: + cmd.append('-K') + cmd.append('UMASK=' + self.umask) + else: + cmd.append('-M') if self.system: cmd.append('-r') @@ -1234,26 +1251,18 @@ class User(object): os.makedirs(path) except OSError as e: self.module.exit_json(failed=True, msg="%s" % to_native(e)) - umask_string = None - # If an umask was set take it from there - if self.umask is not None: - umask_string = self.umask - else: - # try to get umask from /etc/login.defs - 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_string = m.group(1) - # set correct home mode if we have a umask - if umask_string is not None: - umask = int(umask_string, 8) - mode = 0o777 & ~umask - try: - os.chmod(path, mode) - except OSError as e: - 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) + mode = 0o777 & ~umask + try: + os.chmod(path, mode) + except OSError as e: + self.module.exit_json(failed=True, msg="%s" % to_native(e)) def chown_homedir(self, uid, gid, path): try: diff --git a/test/integration/targets/user/tasks/test_local.yml b/test/integration/targets/user/tasks/test_local.yml index 13d7ca30c8f..16c79c57812 100644 --- a/test/integration/targets/user/tasks/test_local.yml +++ b/test/integration/targets/user/tasks/test_local.yml @@ -167,6 +167,3 @@ - name: Test expires for local users import_tasks: test_local_expires.yml - -- name: Test missing home directory parent directory for local users - import_tasks: test_local_missing_parent_dir.yml diff --git a/test/integration/targets/user/tasks/test_local_missing_parent_dir.yml b/test/integration/targets/user/tasks/test_local_missing_parent_dir.yml deleted file mode 100644 index fb992c09b3b..00000000000 --- a/test/integration/targets/user/tasks/test_local_missing_parent_dir.yml +++ /dev/null @@ -1,56 +0,0 @@ ---- -# Create a new local user account with a path that has parent directories that do not exist -- name: Create local user with home path that has parents that do not exist - user: - name: ansibulluser2 - state: present - local: yes - home: "{{ user_home_prefix[ansible_facts.system] }}/in2deep/ansibulluser2" - register: create_home_local_with_no_parent_1 - tags: - - user_test_local_mode - -- name: Create local user with home path that has parents that do not exist again - user: - name: ansibulluser2 - state: present - local: yes - home: "{{ user_home_prefix[ansible_facts.system] }}/in2deep/ansibulluser2" - register: create_home_local_with_no_parent_2 - tags: - - user_test_local_mode - -- name: Check the created home directory - stat: - path: "{{ user_home_prefix[ansible_facts.system] }}/in2deep/ansibulluser2" - register: home_local_with_no_parent_3 - tags: - - user_test_local_mode - -- name: Ensure user with non-existing parent paths was created successfully - assert: - that: - - create_home_local_with_no_parent_1 is changed - - create_home_local_with_no_parent_1.home == user_home_prefix[ansible_facts.system] ~ '/in2deep/ansibulluser2' - - create_home_local_with_no_parent_2 is not changed - - home_local_with_no_parent_3.stat.uid == create_home_local_with_no_parent_1.uid - - home_local_with_no_parent_3.stat.gr_name == default_local_user_group[ansible_facts.distribution] | default('ansibulluser2') - tags: - - user_test_local_mode - -- name: Cleanup test account - user: - name: ansibulluser2 - home: "{{ user_home_prefix[ansible_facts.system] }}/in2deep/ansibulluser2" - state: absent - local: yes - remove: yes - tags: - - user_test_local_mode - -- name: Remove testing dir - file: - path: "{{ user_home_prefix[ansible_facts.system] }}/in2deep/" - state: absent - tags: - - user_test_local_mode diff --git a/test/integration/targets/user/vars/main.yml b/test/integration/targets/user/vars/main.yml index 9fd09236363..4b328f7184b 100644 --- a/test/integration/targets/user/vars/main.yml +++ b/test/integration/targets/user/vars/main.yml @@ -11,6 +11,3 @@ status_command: default_user_group: openSUSE Leap: users MacOSX: admin - -default_local_user_group: - MacOSX: admin