Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

module ldap3 'TypeError: ('expected a byte string in the list'' #48599

angeloudy opened this issue Jul 16, 2018 · 3 comments


None yet
3 participants
Copy link

commented Jul 16, 2018

Description of Issue/Question

I think this pull request #47029 fixed the problem in python2.7 while broke it in python3.
From my experience with python-ldap with python3, when writing back to ldap, the attribute name should be str, while the value should be bytes.

 Comment: An exception occurred in this state: Traceback (most recent call last):
                File "/usr/local/lib/python3.6/site-packages/salt/", line 1905, in call
                File "/usr/local/lib/python3.6/site-packages/salt/", line 1830, in wrapper
                  return f(*args, **kwargs)
                File "/usr/local/lib/python3.6/site-packages/salt/states/", line 327, in managed
                  __salt__['ldap3.change'](l, dn, o, n)
                File "/usr/local/lib/python3.6/site-packages/salt/modules/", line 595, in change
                  l.c.modify_s(dn, modlist)
                File "/usr/local/lib/python3.6/site-packages/ldap/", line 600, in modify_s
                  return self.modify_ext_s(dn,modlist,None,None)
                File "/usr/local/lib/python3.6/site-packages/ldap/", line 572, in modify_ext_s
                  msgid = self.modify_ext(dn,modlist,serverctrls,clientctrls)
                File "/usr/local/lib/python3.6/site-packages/ldap/", line 569, in modify_ext
                  return self._ldap_call(self._l.modify_ext,dn,modlist,RequestControlTuples(serverctrls),RequestControlTuples(clientctrls))
                File "/usr/local/lib/python3.6/site-packages/ldap/", line 294, in _ldap_call
                  result = func(*args,**kwargs)
              TypeError: ('expected a byte string in the list', 'tao')


(Please provide relevant configs and/or SLS files (Be sure to remove sensitive info).)

Steps to Reproduce Issue

(Include debug logs if possible and relevant.)

Versions Report

(Provided by running salt --versions-report. Please also mention any differences in master/minion versions.)

Salt Version:
           Salt: 2018.3.1

Dependency Versions:
           cffi: 1.11.5
       cherrypy: unknown
       dateutil: 2.7.2
      docker-py: Not Installed
          gitdb: Not Installed
      gitpython: Not Installed
          ioflo: Not Installed
         Jinja2: 2.10
        libgit2: Not Installed
        libnacl: Not Installed
       M2Crypto: Not Installed
           Mako: Not Installed
   msgpack-pure: Not Installed
 msgpack-python: 0.5.6
   mysql-python: 1.3.12
      pycparser: 2.18
       pycrypto: 2.6.1
   pycryptodome: Not Installed
         pygit2: Not Installed
         Python: 3.6.5 (default, Jul  2 2018, 00:18:34)
   python-gnupg: Not Installed
         PyYAML: 3.12
          PyZMQ: 17.0.0
           RAET: Not Installed
          smmap: Not Installed
        timelib: Not Installed
        Tornado: 4.5.3
            ZMQ: 4.2.3

System Versions:
         locale: UTF-8
        machine: amd64
        release: 11.2-RELEASE
         system: FreeBSD
        version: Not Installed

This comment has been minimized.

Copy link
Contributor Author

commented Jul 16, 2018

I've made the following changes to make it work.

--- a/salt/modules/
+++ b/salt/modules/
@@ -571,18 +571,15 @@ def change(connect_spec, dn, before, after):
     # convert the "iterable of values" to lists in case that's what
     # modifyModlist() expects (also to ensure that the caller's dicts
     # are not modified)
-    before = dict(((attr, list(vals))
+    before = dict(((attr, [salt.utils.stringutils.to_bytes(val) for val in vals])
                    for attr, vals in six.iteritems(before)))
-    after = dict(((attr, list(vals))
+    after = dict(((attr, [salt.utils.stringutils.to_bytes(val) for val in vals])
                   for attr, vals in six.iteritems(after)))

     if 'unicodePwd' in after:
         after['unicodePwd'] = [_format_unicode_password(x) for x in after['unicodePwd']]

-    modlist =
-        ldap.modlist.modifyModlist(before, after),
-        to_str=True
-    )
+    modlist = ldap.modlist.modifyModlist(before, after)
         l.c.modify_s(dn, modlist)
     except ldap.LDAPError as e:

This comment has been minimized.

Copy link

commented Jul 16, 2018

@angeloudy Thanks for the report. That diff looks good, if you could submit a PR with that fix that would be greatly appreciated.


This comment has been minimized.

Copy link
Contributor Author

commented Jul 17, 2018

This diff worked for me. But I am running salt with python3. I am not sure if it will break it again in python2.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.