简体   繁体   中英

python-ldap3 is unable to add user to and existing LDAP group

I am able successfully connect using LDAP3 and retrieve my LDAP group members as below.

from ldap3 import Server, Connection, ALL, SUBTREE
from ldap3.extend.microsoft.addMembersToGroups import ad_add_members_to_groups as addMembersToGroups

>>> conn = Connection(Server('ldaps://ldap.****.com:***', get_info=ALL),check_names=False, auto_bind=False,user="ANT\*****",password="******", authentication="NTLM")
>>> 
>>> conn.open()
>>> conn.search('ou=Groups,o=****.com', '(&(cn=MY-LDAP-GROUP))', attributes=['cn', 'objectclass', 'memberuid'])
it returns True and I can see members by printing 
conn.entries
>>> 

The above line says MY-LDAP-GROUP exists and returns TRUE while searching but throws LDAP group not found when I try to an user to the group as below

>>> addMembersToGroups(conn, ['myuser'], 'MY-LDAP-GROUP')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/****/anaconda3/lib/python3.7/site-packages/ldap3/extend/microsoft/addMembersToGroups.py", line 69, in ad_add_members_to_groups
    raise LDAPInvalidDnError(group + ' not found')
ldap3.core.exceptions.LDAPInvalidDnError: MY-LDAP-GROUP not found
>>>

The above line says MY-LDAP-GROUP exists and returns TRUE

Returning True just means that the search succeeded. It doesn't mean that anything was found. Is there anything in conn.entries ?

But I suspect your real problem is something different. If this is the source code for ad_add_members_to_groups , then it is expecting the distinguishedName of the group (notice the parameter name group_dn ), but you're passing the cn (common name). For example, your code should be something like:

addMembersToGroups(conn, ['myuser'], 'CN=MY-LDAP-GROUP,OU=Groups,DC=example,DC=com')

If you don't know the DN, then ask for the distinguishedName attribute from the search.

A word of warning: that code for ad_add_members_to_groups retrieves all the current members before adding the new member. You might run into performance problems if you're working with groups that have large membership because of that (eg if the group has 1000 members, it will load all 1000 before adding anyone). You don't actually need to do that (you can add a new member without looking at the current membership). I think what they're trying to avoid is the error you get when you try to add someone who is already in the group. But I think there are better ways to handle that. It might not matter to you if you're only working with small groups.

After so many trial and errors, I got frustrated and used the older python-ldap library to add existing users. Now my code is a mixture of ldap3 and ldap .

I know this is not what the OP has desired. But this may help someone.

Here the user Dinesh Kumar is already part of a group group1. I am trying to add him to another group group2 which is successful and does not disturb the existing group

import ldap
import ldap.modlist as modlist

def add_existing_user_to_group(user_name, user_id, group_id):
    """
    :return:
    """

    # ldap expects a byte string.
    converted_user_name = bytes(user_name, 'utf-8')
    converted_user_id = bytes(user_id, 'utf-8')
    converted_group_id = bytes(group_id, 'utf-8')

    # Add all the attributes for the new dn
    ldap_attr = {}
    ldap_attr['uid'] = converted_user_name
    ldap_attr['cn'] = converted_user_name
    ldap_attr['uidNumber'] = converted_user_id
    ldap_attr['gidNumber'] = converted_group_id
    ldap_attr['objectClass'] =  [b'top', b'posixAccount', b'inetOrgPerson']
    ldap_attr['sn'] = b'Kumar'
    ldap_attr['homeDirectory'] = b'/home/users/dkumar'

    # Establish connection to server using ldap
    conn = ldap.initialize(server_uri, bytes_mode=False)
    bind_resp = conn.simple_bind_s("cn=admin,dc=testldap,dc=com", "password")

    dn_new = "cn={},cn={},ou=MyOU,dc=testldap,dc=com".format('Dinesh Kumar','group2')

    ldif = modlist.addModlist(ldap_attr)
    try:
        response = conn.add_s(dn_new, ldif)
    except ldap.error as e:
        response = e
    print(" The response is ", response)
    conn.unbind()
    return response

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM