From c9fb97cc861030acb3bdc5701935b1e84b82800d Mon Sep 17 00:00:00 2001 From: Toshio Kuratomi Date: Mon, 16 Feb 2015 07:07:58 -0800 Subject: [PATCH] Be careful not to set the permissions of the destination of a symlink. It's up to the module using the set_fs_attributes*/set_mode* methods to specify the filename of the destination of the symlink if that's really the file that should be modified. Half of the fix for: https://github.com/ansible/ansible-modules-core/issues/778 --- lib/ansible/module_utils/basic.py | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/lib/ansible/module_utils/basic.py b/lib/ansible/module_utils/basic.py index 8b14536ab53..4412291dff1 100644 --- a/lib/ansible/module_utils/basic.py +++ b/lib/ansible/module_utils/basic.py @@ -656,14 +656,25 @@ class AnsibleModule(object): # FIXME: comparison against string above will cause this to be executed # every time try: - if 'lchmod' in dir(os): + if hasattr(os, 'lchmod'): os.lchmod(path, mode) else: - os.chmod(path, mode) + if not os.path.islink(path): + os.chmod(path, mode) + else: + # Attempt to set the perms of the symlink but be + # careful not to change the perms of the underlying + # file while trying + underlying_stat = os.stat(path) + os.chmod(path, mode) + new_underlying_stat = os.stat(path) + if underlying_stat.st_mode != new_underlying_stat.st_mode: + os.chmod(path, stat.S_IMODE(underlying_stat.st_mode)) + q_stat = os.stat(path) except OSError, e: if os.path.islink(path) and e.errno == errno.EPERM: # Can't set mode on symbolic links pass - elif e.errno == errno.ENOENT: # Can't set mode on broken symbolic links + elif e.errno in (errno.ENOENT, errno.ELOOP): # Can't set mode on broken symbolic links pass else: raise e