【问题标题】:Process LDIF modify records with python-ldap使用 python-ldap 处理 LDIF 修改记录
【发布时间】:2021-11-02 21:17:28
【问题描述】:

我正在使用 python-ldap 处理一个 LDIF 文件并(有条件地)将该文件中的记录导入 LDAP 服务器。我能找到的每一个文档和每一个例子,都只是假设 LDIF 记录是additions。但是,我的脚本处理的 LDIF 文件是具有 changetype 的版本 1 文件,如下所示:

version: 1

dn: cn=group,ou=groups,o=vault
changetype: add
cn: group
mail: group@a.org
member: cn=users,ou=users,o=vault

dn:cn=users,ou=users,o=vault
changetype: modify
add: memberOf
memberOf: cn=group,ou=groups,o=vault
-

根据python-ldap的文档,我需要使用modlist.addModlist 进行添加和modlist.modifyModlist 进行修改。

我的问题是:如何从解析的 LDIF 数据中获取 LDAP 中的修改? 大致如下:

parser = ldif.LDIFRecordList(open(filename,'r'))
parser.parse()
for dn, entry in parser.all_records:
    if entry['changetype'] == "add":
        crud = modlist.addModlist(entry)
        ldapcon.add_s(dn,crud)
    else:
        crud = modlist.modifyModlist(entry)
        ldapcon.modify_s(dn,crud)

上述方法不起作用; modlist.modifyModlist() 需要两个参数。 此外,entry 在元组数组中仅包含来自 LDIF 的确切行,包括 changetype 和(强制)分隔线,带有单个破折号:-(

我真的需要逐行解析输入数据并创建自己的修改吗?如果是这样,LDIF 解析器的附加值是多少?

【问题讨论】:

    标签: python ldap python-ldap ldif


    【解决方案1】:

    首先,您应该在解析器的句柄方法中处理条目,而不是在解析所有记录后在外部循环中处理条目。所以这个:

    class myParser( LDIFParser ):
    
        def handle( self, dn, entry ):
            # Your code/logic here...
    
    parser = myParser( open(....
    parser.parse()
    

    代替:

    parser = myParser( open(...
    parser.parse()
    
    for dn, entry...
    

    至于 modlist,您需要传递旧条目(handle 方法中显示的字典)和一个新的、修改后的字典,其中包含所有未更改的项、新项、已修改项且不包含已删除项。像这样的:

    class myParser( LDIFParser ):
    
        def handle( self, dn, entry ):
    
            # Filter for objectClass if needed
            if b'some_class' not in entry['objectClass']:
                return
            
            # new_entry is a copy of old entry
            new_entry = entry.copy()
        
            # Add an attribute named 'add_new'
            new_entry['add_new'] = 'Added'
        
            # Modify an attribute named 'modify existing'
            new_entry['modify_existing'] = [b'99']
        
            print( 'OLD:', entry )
            print( 'NEW:', new_entry )
        
            print( ldap.modlist.modifyModlist( entry, new_entry ) )
    

    【讨论】:

    • 感谢您的回复。您的示例还假设完整条目,而不是修改条目。在进行更多测试并查看 LDIF 解析器源代码后,我得出结论,无法处理 LDIF 修改记录。
    【解决方案2】:

    我做了更多的研究和测试。

    使用当前版本 (3.3.1) 的 python-ldap 无法可靠地处理 LDIF 修改记录。考虑以下 LDIF sn-p:

    dn: cn=user,ou=org
    changetype: modify
    add: memberOf
    memberOf: cn=group,o=org
    -
    delete: description
    description: groupless
    -
    add: description
    description: grouped
    -
    

    当使用 python-ldap 从 LDIF 文件中读取此内容时,数据将传输到带有 key: [value] 条目的 dict。 但是dict 不允许重复键,因此键会被合并,这是不可取的。

    这是生成的dict

    {'changetype': [b'modify'], 'add': [b'memberOf', b'description'], 
     'memberOf': [b'cn=group,o=org'], '-': [None, None, None], 
     'delete': [b'description'], 'description': [b'groupless', b'grouped']}
    

    如您所见,不再可能确定应该先执行哪个操作(添加或删除),或者应该删除哪个值以及添加哪个值(无组或分组)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-10-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多