From df877f2e79f3b5ddceb84dea6ee0dcd881e7c830 Mon Sep 17 00:00:00 2001 From: James Cammarata Date: Tue, 13 May 2014 13:52:38 -0500 Subject: [PATCH] Check module_path permissions when creating ssh_wrapper for git If the module directory is not writable/executable to the current user (most likely because of a sudo to a non-root user), the ssh_wrapper will be created in the default location for mkstemp() calls. To facilitate the deletion of these new files, a new mechanism for cleaning up files created by the module was also added. Fixes #7375 --- lib/ansible/module_utils/basic.py | 13 ++++++++++++- library/source_control/git | 11 ++++++++++- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/lib/ansible/module_utils/basic.py b/lib/ansible/module_utils/basic.py index 681a973801e..23c7b15800f 100644 --- a/lib/ansible/module_utils/basic.py +++ b/lib/ansible/module_utils/basic.py @@ -182,6 +182,7 @@ class AnsibleModule(object): self.supports_check_mode = supports_check_mode self.check_mode = False self.no_log = no_log + self.cleanup_files = [] self.aliases = {} @@ -898,11 +899,20 @@ class AnsibleModule(object): def from_json(self, data): return json.loads(data) + def add_cleanup_file(self, path): + if path not in self.cleanup_files: + self.cleanup_files.append(path) + + def do_cleanup_files(self): + for path in self.cleanup_files: + self.cleanup(path) + def exit_json(self, **kwargs): ''' return from the module, without error ''' self.add_path_info(kwargs) if not 'changed' in kwargs: kwargs['changed'] = False + self.do_cleanup_files() print self.jsonify(kwargs) sys.exit(0) @@ -911,6 +921,7 @@ class AnsibleModule(object): self.add_path_info(kwargs) assert 'msg' in kwargs, "implementation error -- msg to explain the error is required" kwargs['failed'] = True + self.do_cleanup_files() print self.jsonify(kwargs) sys.exit(1) @@ -958,7 +969,7 @@ class AnsibleModule(object): self.fail_json(msg='Could not make backup of %s to %s: %s' % (fn, backupdest, e)) return backupdest - def cleanup(self,tmpfile): + def cleanup(self, tmpfile): if os.path.exists(tmpfile): try: os.unlink(tmpfile) diff --git a/library/source_control/git b/library/source_control/git index 6af4bd7179e..98b37ae02eb 100644 --- a/library/source_control/git +++ b/library/source_control/git @@ -181,7 +181,15 @@ def get_submodule_update_params(module, git_path, cwd): def write_ssh_wrapper(): module_dir = get_module_path() - fd, wrapper_path = tempfile.mkstemp(prefix=module_dir + '/') + try: + # make sure we have full permission to the module_dir, which + # may not be the case if we're sudo'ing to a non-root user + if os.access(module_dir, os.W_OK|os.R_OK|os.X_OK): + fd, wrapper_path = tempfile.mkstemp(prefix=module_dir + '/') + else: + raise OSError + except (IOError, OSError): + fd, wrapper_path = tempfile.mkstemp() fh = os.fdopen(fd, 'w+b') template = """#!/bin/sh if [ -z "$GIT_SSH_OPTS" ]; then @@ -505,6 +513,7 @@ def main(): if key_file or ssh_opts: ssh_wrapper = write_ssh_wrapper() set_git_ssh(ssh_wrapper, key_file, ssh_opts) + module.add_cleanup_file(path=ssh_wrapper) # add the git repo's hostkey if module.params['ssh_opts'] is not None: