Don't send unicode instances to the selinux module

This fixes #2632.  Briefly: specifying things like paths using complex
args in a playbook will make the objects unicode instances.  The selinux
module does not accept unicode instances for its char * arguments; it
wants str instances.

Per mpdehaan's comment on #2632 I just went ahead and converted all
paths to UTF-8.  I don't know if it would be better to do something like
converting to locale.getpreferredencoding(), but I factored all the
conversions out into new method _to_filesystem_str, so there's only one
place that needs to be changed in the future.
pull/2727/head
Dale Sedivec 12 years ago
parent 66afe13346
commit c8f4a56cad

@ -271,13 +271,26 @@ class AnsibleModule(object):
context.append(None) context.append(None)
return context return context
def _to_filesystem_str(self, path):
'''Returns filesystem path as a str, if it wasn't already.
Used in selinux interactions because it cannot accept unicode
instances, and specifying complex args in a playbook leaves
you with unicode instances. This method currently assumes
that your filesystem encoding is UTF-8.
'''
if isinstance(path, unicode):
path = path.encode("utf-8")
return path
# If selinux fails to find a default, return an array of None # If selinux fails to find a default, return an array of None
def selinux_default_context(self, path, mode=0): def selinux_default_context(self, path, mode=0):
context = self.selinux_initial_context() context = self.selinux_initial_context()
if not HAVE_SELINUX or not self.selinux_enabled(): if not HAVE_SELINUX or not self.selinux_enabled():
return context return context
try: try:
ret = selinux.matchpathcon(path, mode) ret = selinux.matchpathcon(self._to_filesystem_str(path), mode)
except OSError: except OSError:
return context return context
if ret[0] == -1: if ret[0] == -1:
@ -290,7 +303,7 @@ class AnsibleModule(object):
if not HAVE_SELINUX or not self.selinux_enabled(): if not HAVE_SELINUX or not self.selinux_enabled():
return context return context
try: try:
ret = selinux.lgetfilecon(path) ret = selinux.lgetfilecon(self._to_filesystem_str(path))
except OSError, e: except OSError, e:
if e.errno == errno.ENOENT: if e.errno == errno.ENOENT:
self.fail_json(path=path, msg='path %s does not exist' % path) self.fail_json(path=path, msg='path %s does not exist' % path)
@ -340,7 +353,8 @@ class AnsibleModule(object):
try: try:
if self.check_mode: if self.check_mode:
return True return True
rc = selinux.lsetfilecon(path, ':'.join(new_context)) rc = selinux.lsetfilecon(self._to_filesystem_str(path),
str(':'.join(new_context)))
except OSError: except OSError:
self.fail_json(path=path, msg='invalid selinux context', new_context=new_context, cur_context=cur_context, input_was=context) self.fail_json(path=path, msg='invalid selinux context', new_context=new_context, cur_context=cur_context, input_was=context)
if rc != 0: if rc != 0:

Loading…
Cancel
Save