Search code examples
pythonlinuxactive-directoryldap

Run AD queries with Python from a Linux machine


I am developing a Flask Web-App that should require LDAP authentication. However, because some users are under different OUs and sometimes the CN != ldap_username and I want to get the LDAP destinguishedName by querying the username. I know that in Windows PowerShell I can use Get-ADUser username but I want to do this on Linux since I am running my app on a linux machine.

I have tried python-ldap3 and I can authenticate to the LDAP server however, I can't run AD Queries (At least I don't know an option to do so) and I have read through the docs but didn't find something that could be of help.

Please note that I want to query on the Active Directory by Username, like the Get-ADUser command.


Solution

  • You would first have to be connected to the LDAP server in order to query on it, so firstly you will have to have a user that has permissions to query on the AD.

    You say you have succeeded to connect to the LDAP Server so I figure you already know the user's DN (The one you're using)

    In order to connect this code would work:

    from ldap3 import Server, Connection
    
    DN = 'ou=Users,dc=example,dc=com' # This changes depending on your domain architecture
    USERNAME = 'cn=user,' + BASE_DN
    PASSWORD = 'SuperSecretPass!'
    SERVER = 'ldap://server_ip:389' 
    
    ldap_server = Server(SERVER, get_info=ALL)
    conn = Connection(ldap_server, user=USERNAME, password=PASSWORD, auto_bind=True)
    

    With this you have initialized a connection to the LDAP Server and now in order to query for a specific user you can use the function Connection.search() and apply a search filter that finds the required user.

    You will also have to provide the search with the base_dn that should represent under which OU the user exists, if you don't know the specific OU or the user is under a few sub OUs , then you can put the top OU (Which is ultimately Users) and it should recurse until it finds it.

    # Assumming base_dn == DN I will just use it as the base dn
    username = 'user_to_query'
    search_filter = f'(sAMAccountName={username})'
    
    # In your case you only want DN so this option is not needed but this returns the complete summary of the user
    attributes = '*' 
    
    query = conn.search(DN, search_filter, attributes=attributes)
    
    # Get the DN from the query_result
    if query:
        print(conn.entries[0].entry_dn)
    else:
        print("User not found")