简体   繁体   English

使用 python-ldap 处理 LDIF 修改记录

[英]Process LDIF modify records with python-ldap

I am using python-ldap to process an LDIF file and (conditionally) import the records from that file into an LDAP server.我正在使用python-ldap来处理 LDIF 文件并(有条件地)将该文件中的记录导入到 LDAP 服务器中。 Every piece of documentation and every example I can find, just assumes LDIF records are additions .我能找到的每一份文档和每一个例子,都假设 LDIF 记录是附加的 However the LDIF files my script processes are version 1 files with a changetype , like so:但是,我的脚本处理的 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
-

According to the documentation of python-ldap I need to use modlist.addModlist for adds and modlist.modifyModlist for modifications.根据python-ldap的文档,我需要使用modlist.addModlist添加和modlist.modifyModlist进行修改。

My question is: how do I get from the parsed LDIF data to a modification in LDAP?我的问题是:如何从解析的 LDIF 数据获取到 LDAP 中的修改? Something along the lines of:类似的东西:

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)

The above does not work;以上不起作用; modlist.modifyModlist() requires two arguments. modlist.modifyModlist()需要两个参数。 Also, the entry contains just the exact lines from the LDIF in an array of tuples, including the changetype and the (mandatory) separator line with the single dash :-(此外,该entry仅包含元组数组中来自 LDIF 的确切行,包括 changetype 和(强制)分隔符行和单破折号 :-(

Do I really need to parse the entry data line by line and create my own modifications?我真的需要逐行解析条目数据并创建自己的修改吗? What is the added value of the LDIF parser if that is the case?如果是这种情况,LDIF 解析器的附加价值是什么?

First of all, you should be processing entries in parser's handle method instead of in an external loop after all of the records have been parsed.首先,在解析完所有记录后,您应该在解析器的 handle 方法中而不是在外部循环中处理条目。 So this:所以这:

class myParser( LDIFParser ):

    def handle( self, dn, entry ):
        # Your code/logic here...

parser = myParser( open(....
parser.parse()

instead of:代替:

parser = myParser( open(...
parser.parse()

for dn, entry...

As for the modlist, you need to pass the old entry (dictionary as presented in the handle method) and a new, modified dictionary with all unchanged items, new ones, modified ones and without the deleted ones.至于 modlist,您需要传递旧条目(handle 方法中显示的字典)和一个新的、修改过的字典,其中包含所有未更改的项、新项、修改项并且没有删除项。 Something like this:像这样的东西:

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 ) )

I did more research and tests.我做了更多的研究和测试。

With the current version (3.3.1) of python-ldap it is not possible to reliably process LDIF modify records.使用 python-ldap 的当前版本 (3.3.1),不可能可靠地处理 LDIF 修改记录。 Consider the following LDIF snippet:考虑以下 LDIF 片段:

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

When reading this from an LDIF file with python-ldap, the data is transferred to a dict with key: [value] entries.使用 python-ldap 从 LDIF 文件读取此文件时,数据将传输到带有key: [value]条目的dict However dict does not allow duplicate keys so the keys are merged which is undesirable.但是dict不允许重复的键,因此键被合并,这是不可取的。

This is the resulting 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']}

As you can see, it is no longer possible to determine which operation should come first (add or delete), or which value should be deleted and which value added (groupless or grouped).如您所见,不再可能确定应该先执行哪个操作(添加或删除),或者应该删除哪个值以及添加哪个值(无组或分组)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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