diff --git a/lib/ansible/cli/vault.py b/lib/ansible/cli/vault.py index a4329056f9..d6ca1d436b 100644 --- a/lib/ansible/cli/vault.py +++ b/lib/ansible/cli/vault.py @@ -86,6 +86,9 @@ class VaultCLI(CLI): super(VaultCLI, self).run() loader = DataLoader() + # set default restrictive umask + old_umask = os.umask(0o077) + if self.options.vault_password_file: # read vault_pass from a file self.vault_pass = CLI.read_vault_password_file(self.options.vault_password_file, loader) @@ -108,6 +111,9 @@ class VaultCLI(CLI): self.execute() + # and restore umask + os.umask(old_umask) + def execute_encrypt(self): if len(self.args) == 0 and sys.stdin.isatty(): diff --git a/lib/ansible/parsing/vault/__init__.py b/lib/ansible/parsing/vault/__init__.py index 7d9b84b8d2..ac904748a3 100644 --- a/lib/ansible/parsing/vault/__init__.py +++ b/lib/ansible/parsing/vault/__init__.py @@ -221,8 +221,6 @@ class VaultEditor: self.vault = VaultLib(password) def _edit_file_helper(self, filename, existing_data=None, force_save=False): - # make sure the umask is set to a sane value - old_umask = os.umask(0o077) # Create a tempfile _, tmp_path = tempfile.mkstemp() @@ -246,9 +244,6 @@ class VaultEditor: # shuffle tmp file into place self.shuffle_files(tmp_path, filename) - # and restore umask - os.umask(old_umask) - def encrypt_file(self, filename, output_file=None): check_prereqs() @@ -303,13 +298,19 @@ class VaultEditor: check_prereqs() + prev = os.stat(filename) ciphertext = self.read_data(filename) plaintext = self.vault.decrypt(ciphertext) new_vault = VaultLib(new_password) new_ciphertext = new_vault.encrypt(plaintext) + self.write_data(new_ciphertext, filename) + # preserve permitions + os.chmod(filename, prev.st_mode) + os.chown(filename, prev.st_uid, prev.st_gid) + def read_data(self, filename): try: if filename == '-': @@ -333,11 +334,19 @@ class VaultEditor: fh.write(bytes) def shuffle_files(self, src, dest): + prev = None # overwrite dest with src if os.path.isfile(dest): + prev = os.stat(dest) os.remove(dest) shutil.move(src, dest) + # reset permissions if needed + if prev is not None: + #TODO: selinux, ACLs, xattr? + os.chmod(dest, prev.st_mode) + os.chown(dest, prev.st_uid, prev.st_gid) + def _editor_shell_command(self, filename): EDITOR = os.environ.get('EDITOR','vim') editor = shlex.split(EDITOR)