Python LDAP write attribute to Active Directory
Asked Answered
G

3

6

I am able to bind and query Active Directory via python-ldap without any issues except when it comes to adding or modifying attributes on AD. I can add the attribute but the encoding seems to be way off as all the text is garbled.

I've tried encoding my string with utf8 and a few others with no luck.

I've also tried binding with a Domain Admin account along with binding with the user account to which I will be changing an attribute, same result regardless.

Here is the method I use to update an attribute:

class LdapHelpers:

def __init__(self):
    import ldap

    # set globals
    self.server = 'LDAP://dc.mycompany.com'
    self.admin_dn = 'CN=Administrator,CN=users,DC=mycompany,DC=com'
    self.admin_pass = 'coolpassword'

    # init LDAP connection
    #ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, 0)
    ldap.set_option(ldap.OPT_REFERRALS, 0)
    ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER)
    ldap.protocol_version = ldap.VERSION3
    self.ldap = ldap.initialize(self.server)

def update_attribute(self, attrib, value):
    try:
        import ldap
        conn = self.ldap
        conn.simple_bind_s(self.admin_dn, self.admin_pass)
        mod_attrs = [( ldap.MOD_REPLACE, "mobile", "6306564123")]

        # I have tried other variations of the above
        # mod_attrs = [( ldap.MOD_REPLACE, "mobile", "6306564123".encode('utf-8)]

        conn.modify_s('CN=Mike Smith,OU=GoogleApps,DC=company,DC=com', mod_attrs)
        print 'record updated'

    except ldap.LDAPError as e:
        return e.message

Doing a ldapsearch via terminal this is what the attribute looks like:

mobile:: MC8sAQAAAAAQNA==

This is what 'Hello World' looks like when I set mobile to it:

mobile:: 77+9ehsCAAAAABDvv70V

I've checked MSDN and it says that ldap attribute is just a Unicode string.

System: Ubuntu 15.10 64bit Python: 2.7.10 python-ldap==2.4.21

As a side note I can search AD without any issues and parse/display returned user attributes, the issue only seems to be with creating or modifying attributes that this encoding issue comes in to play.

Gaal answered 9/12, 2015 at 21:35 Comment(2)
could you please check what query it is sent tcpflow -c port 389?Eminence
Here is the dump from the modify query above: tcpflow -c port 389 tcpflow: listening on eth0 010.001.200.029.54760-010.000.000.039.00389: 0C`>-CN=Administrator,CN=users,DC=company,DC=com coolpassword 010.000.000.039.00389-010.001.200.029.54760: 0a 010.001.200.029.54760-010.000.000.039.00389: 0[fV4CN=Jassen Michaels,OU=GoogleApps,DC=company,DC=com00 pmobile1 010.000.000.039.00389-010.001.200.029.54760: 0gGaal
G
0

Ok I found out what was going on, I was using PyPy 4.0.1 as the interpreter and for some reason this was either causing issues with the python-ldap library and/or encoding for strings.

I switched back to Python 2.7.10 for the interpreter and now the very same modify commands up above work as expected using the python-ldap library. So definitely a word of caution if using PyPy and this particular library....

Gaal answered 15/12, 2015 at 16:24 Comment(0)
R
0

The '=' at the end is often an indicator that it is Base64 encoding. Python has a standard library for encoding/decoding base64 (The link is for Python 3, but Python 2 also has the library). LDAP does indeed use Base64 for something. See The LDAP Data Interchange Format (LDIF).

Rochelrochell answered 10/12, 2015 at 2:55 Comment(2)
Thanks for the reply. There seems to be something weird with the encoding, for example if I modify the mobile attribute and set it to 'Hello World' it is stored in AD as: mobile:: 77+9ehsCAAAAABDvv70V That doesn't decode to anything in Base64 other than gibberish. If I am using OpenLDAP from the command line I can create an .ldif file to modify that attribute and it will show up correctly, so I am not sure if this is something specifically tied to python-LDAP and AD?Gaal
I also saw that the double colon's in the LDAP Search result signify the item in Base64 encoded, though if I modify the attribute via an LDIF file the attribute does not get encoded, it only seems to behave this way when I am trying to modify attributes via python rather than using openLDAP commands...Gaal
F
0

Take a look at the code from pyad to clarify what to do: https://pypi.python.org/pypi/pyad

It's Python-based.

Another example at already answered question: Use Python script to manage remote LDAP server

Filmer answered 14/12, 2015 at 20:42 Comment(2)
The adLDAP link you provided is a PHP library not Python. I have also looked at the other link already as well, I can bind and search against my AD without any problems, though when I modify attribs it gets encoded in a weird character set, even using the same code from the example you providedGaal
wow, you are right, looks like I'm out of my mind today! Sorry about that. I meant to point to pypi.python.org/pypi/pyadFilmer
G
0

Ok I found out what was going on, I was using PyPy 4.0.1 as the interpreter and for some reason this was either causing issues with the python-ldap library and/or encoding for strings.

I switched back to Python 2.7.10 for the interpreter and now the very same modify commands up above work as expected using the python-ldap library. So definitely a word of caution if using PyPy and this particular library....

Gaal answered 15/12, 2015 at 16:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.