diff --git a/lib/ansible/runner/connection_plugins/ssh.py b/lib/ansible/runner/connection_plugins/ssh.py index ece1021f855..2958bdadab3 100644 --- a/lib/ansible/runner/connection_plugins/ssh.py +++ b/lib/ansible/runner/connection_plugins/ssh.py @@ -43,6 +43,7 @@ class Connection(object): self.user = user self.password = password self.private_key_file = private_key_file + self.cp_dir = utils.prepare_writeable_dir('$HOME/.ansible/cp',mode=0700) self.HASHED_KEY_MAGIC = "|1|" def connect(self): @@ -57,7 +58,18 @@ class Connection(object): else: self.common_args += ["-o", "ControlMaster=auto", "-o", "ControlPersist=60s", - "-o", "ControlPath=/tmp/ansible-ssh-%h-%p-%r"] + "-o", "ControlPath=%s/ansible-ssh-%%h-%%p-%%r" % self.cp_dir] + + cp_in_use = False + cp_path_set = False + for arg in self.common_args: + if arg.find("ControlPersist") != -1: + cp_in_use = True + if arg.find("ControlPath") != -1: + cp_path_set = True + + if cp_in_use and not cp_path_set: + self.common_args += ["-o", "ControlPath=%s/ansible-ssh-%%h-%%p-%%r" % self.cp_dir] if not C.HOST_KEY_CHECKING: self.common_args += ["-o", "StrictHostKeyChecking=no"] diff --git a/lib/ansible/utils/__init__.py b/lib/ansible/utils/__init__.py index 751052004e8..0d3ad7d952d 100644 --- a/lib/ansible/utils/__init__.py +++ b/lib/ansible/utils/__init__.py @@ -193,18 +193,34 @@ def is_executable(path): or stat.S_IXGRP & os.stat(path)[stat.ST_MODE] or stat.S_IXOTH & os.stat(path)[stat.ST_MODE]) -def prepare_writeable_dir(tree): +def unfrackpath(path): + ''' + returns a path that is free of symlinks, environment + variables, relative path traversals and symbols (~) + example: + '$HOME/../../var/mail' becomes '/var/spool/mail' + ''' + return os.path.normpath(os.path.realpath(os.path.expandvars(os.path.expanduser(path)))) + +def prepare_writeable_dir(tree,mode=0777): ''' make sure a directory exists and is writeable ''' - if tree != '/': - tree = os.path.realpath(os.path.expanduser(tree)) + # modify the mode to ensure the owner at least + # has read/write access to this directory + mode |= 0700 + + # make sure the tree path is always expanded + # and normalized and free of symlinks + tree = unfrackpath(tree) + if not os.path.exists(tree): try: - os.makedirs(tree) + os.makedirs(tree, mode) except (IOError, OSError), e: exit("Could not make dir %s: %s" % (tree, e)) if not os.access(tree, os.W_OK): exit("Cannot write to path %s" % tree) + return tree def path_dwim(basedir, given): '''