Python ldap 2.7.15 не может интерпретировать атрибуты - PullRequest
0 голосов
/ 31 августа 2018

После компиляции Python 2.7.15 из исходного кода и установки в RedHat Enterprise 6.x я заметил существенную разницу в ldap.modlist между 2.7.12 и 2.7.15. Это существенно влияет на нашу реализацию Ansible (которая использует LDAP в качестве источника для сценария hosts).

Следующий пример кода:

import ldap.modlist as ml

d = { 'a': 'word', 'cn': 'ou=example,ou=com' }
e = { 'a': 'other word', 'cn': 'ou=example,ou=com'}

ldif = ml.modifyModlist(d, e)
print str(ldif)

Вывод в соответствии с 2.7.12 (который выглядит правильно)

[(1, «а», нет), (0, «а», «другое слово»)]

Вывод в 2.7.15 (который отображается неверно)

[(1, 'a', нет), (0, 'a', ['o', 't', 'h', 'e', 'r', '', 'w', 'o', 'r', 'd'])]

Это известная ошибка? Кому я должен представить это? (GitHub?)

Вот "diff" между 2 исходными файлами ldap.modlist:

ВЕРСИЯ 2.7.15 - ">" ВЕРСИЯ 2.7.12 это "<" </p>

PS1=> diff /Library/Python/2.7.12/site-packages/ldap/modlist.py /tmp/py2.7.15/build_modlist.py 
4,10c4
< See http://www.python-ldap.org/ for details.
< 
< $Id: modlist.py,v 1.18 2011/06/06 13:07:38 stroeder Exp $
< 
< Python compability note:
< This module is known to work with Python 2.0+ but should work
< with Python 1.5.2 as well.
---
> See https://www.python-ldap.org/ for details.
15,31c9
< import string,ldap,ldap.cidict
< 
< 
< def list_dict(l,case_insensitive=0):
<   """
<   return a dictionary with all items of l being the keys of the dictionary
< 
<   If argument case_insensitive is non-zero ldap.cidict.cidict will be
<   used for case-insensitive string keys
<   """
<   if case_insensitive:
<     d = ldap.cidict.cidict()
<   else:
<     d = {}
<   for i in l:
<     d[i]=None
<   return d
---
> import ldap
36c14
<   ignore_attr_types = list_dict(map(string.lower,(ignore_attr_types or [])))
---
>   ignore_attr_types = {v.lower() for v in ignore_attr_types or []}
38,39c16,17
<   for attrtype in entry.keys():
<     if ignore_attr_types.has_key(string.lower(attrtype)):
---
>   for attrtype, value in entry.items():
>     if attrtype.lower() in ignore_attr_types:
43c21
<     attrvaluelist = filter(lambda x:x!=None,entry[attrtype])
---
>     attrvaluelist = [item for item in value if item is not None]
45c23
<       modlist.append((attrtype,entry[attrtype]))
---
>       modlist.append((attrtype, value))
71,72c49,50
<   ignore_attr_types = list_dict(map(string.lower,(ignore_attr_types or [])))
<   case_ignore_attr_types = list_dict(map(string.lower,(case_ignore_attr_types or [])))
---
>   ignore_attr_types = {v.lower() for v in ignore_attr_types or []}
>   case_ignore_attr_types = {v.lower() for v in case_ignore_attr_types or []}
76,79c54,57
<     attrtype_lower_map[string.lower(a)]=a
<   for attrtype in new_entry.keys():
<     attrtype_lower = string.lower(attrtype)
<     if ignore_attr_types.has_key(attrtype_lower):
---
>     attrtype_lower_map[a.lower()]=a
>   for attrtype, value in new_entry.items():
>     attrtype_lower = attrtype.lower()
>     if attrtype_lower in ignore_attr_types:
83,84c61,62
<     new_value = filter(lambda x:x!=None,new_entry[attrtype])
<     if attrtype_lower_map.has_key(attrtype_lower):
---
>     new_value = [item for item in value if item is not None]
>     if attrtype_lower in attrtype_lower_map:
86c64
<       old_value = filter(lambda x:x!=None,old_value)
---
>       old_value = [item for item in old_value if item is not None]
97,110c75,81
<         case_insensitive = case_ignore_attr_types.has_key(attrtype_lower)
<         old_value_dict=list_dict(old_value,case_insensitive)
<         new_value_dict=list_dict(new_value,case_insensitive)
<         delete_values = []
<         for v in old_value:
<           if not new_value_dict.has_key(v):
<             replace_attr_value = 1
<             break
<         add_values = []
<         if not replace_attr_value:
<           for v in new_value:
<             if not old_value_dict.has_key(v):
<               replace_attr_value = 1
<               break
---
>         if attrtype_lower in case_ignore_attr_types:
>           old_value_set = {v.lower() for v in old_value}
>           new_value_set = {v.lower() for v in new_value}
>         else:
>           old_value_set = set(old_value)
>           new_value_set = set(new_value)
>         replace_attr_value = new_value_set != old_value_set
120,121c91,92
<     for a in attrtype_lower_map.keys():
<       if ignore_attr_types.has_key(a):
---
>     for a, val in attrtype_lower_map.items():
>       if a in ignore_attr_types:
124c95
<       attrtype = attrtype_lower_map[a]
---
>       attrtype = val

1 Ответ

0 голосов
/ 31 августа 2018

Хороший четкий ответ от сообщества Ldap

Краткий ответ:

Поведение, замеченное в Python 2.7.12 (с python-ldap == 2.4.38), является неопределенное и непреднамеренное поведение. Значения атрибута LDAP всегда многозначный (списки). python-ldap 3.1 применяет списки как атрибуты. Вы должны написать свой атрибут dict как {'a': ['word'], 'cn': [ 'НУ = пример, НУ = ком']}.

Кредит Кристиан Хаймс

...