LDAP AD - 范围属性,如何使用它?

时间:2009-06-16 09:57:28

标签: ldap

我正在尝试使用范围属性。

为了测试,我使用没有范围返回3个条目的搜索,并且我将范围设置为0-1,这应该仅返回前2个。但是,我得到所有3个结果。

我就是这样做的:

String rangeStr = attribute + ";range=0-1";
String returnedAttrs[] = {rangeStr, attribute};
_searchControls.setReturningAttributes(returnedAttrs);
_searchControls.setSearchScope(scope);
NamingEnumeration<SearchResult> answer = _context.search(name, filter, _searchControls);
List<String> result = new LinkedList<String>();
while (answer != null && answer.hasMoreElements())
{
    Attribute currentAttr = answer.next().getAttributes().get(attribute);
    if (currentAttr == null)
        continue;
    for (int i=0; i<currentAttr.size(); i++)
    {
        String val = currentAttr.get(i).toString();
        result.add(val);
    }
}

我做错了什么?

我使用的页面大小为1000,但如果我理解正确,则不应该影响远程搜索(假设页面大小大于请求的范围)。这是对的吗?

2 个答案:

答案 0 :(得分:6)

#!/usr/bin/env python

import ldap

def msad_flatten_ranges(conn, dn, ldap_dict):
  for attrname in ldap_dict:
    if ';range=' in attrname:
      #
      # parse range attr
      #
      actual_attrname, range_stmt = attrname.split(';')
      bound_lower, bound_upper = [
        int(x) for x in range_stmt.split('=')[1].split('-')
      ]

      step = bound_upper - bound_lower + 1
      while True:
        attr_next = '%s;range=%d-%d' % (
          actual_attrname, bound_lower, bound_upper
        )

        dn, attrs = conn.search_s(
          dn, ldap.SCOPE_BASE, attrlist = [attr_next])[0]

        assert len(attrs) == 1

        ret_attrname = attrs.keys()[0]

        ldap_dict[actual_attrname].extend(attrs[ret_attrname])
        if ret_attrname.endswith('-*'):
          break

        bound_lower = bound_upper + 1
        bound_upper += step

答案 1 :(得分:0)

我还没有对 Russell 的帖子发表评论的声誉,但我不得不稍微调整他的回答才能在 python3 + ldap 3.3.1 下工作。 (但感谢罗素,您的初步解决方案。)

首先,我用另一个函数包装了他的函数以循环浏览我之前搜索的结果:

  for result in results:
      dn, obj = result

      msad_flatten_ranges(conn dn, obj)

(抱歉,我知道这太明显了 - 我是为新手添加的。)

然后我修改了他的函数:

def msad_flatten_ranges(conn, dn, ldap_dict):
  ranged_attrs = [ attrib for attrib in ldap_dict if ';range=' in attrib ]

  for attrname in ranged_attrs:
    #
    # parse range attr
    #
    actual_attrname, range_stmt = attrname.split(';')

    ldap_dict[actual_attrname] = ldap_dict.pop(attrname)

    bound_lower, bound_upper = [ 
      int(x) for x in range_stmt.split('=')[1].split('-')
    ]

    step = bound_upper - bound_lower + 1

    while True:
      bound_lower = bound_upper + 1
      bound_upper += step

      attr_next = '%s;range=%d-%d' % (
        actual_attrname, bound_lower, bound_upper
      )

      dn, attrs = conn.search_s(
        dn, ldap.SCOPE_BASE, attrlist = [attr_next])[0]

      assert len(attrs) == 1

      ret_attrname = tuple(attrs.keys())[0]

      ldap_dict[actual_attrname].extend(attrs[ret_attrname])
      if ret_attrname.endswith('-*'):
        break

变化如下:

  1. 我预先确定了需要扩展的属性 (ranged_attrs),因为我不希望对 ldap_dict 键进行任何更改来破坏外循环。
  2. 我将现有的(初始)范围转换为 actual_attrname 条目,以避免再次重新获取相同的范围(请参阅带有 ldap_dict.pop(attrname) 的行),这解决了该 dict 键已经存在的需要因为后来的“扩展”电话对我来说被打破了。 “pop”删除键值的范围版本。
  3. 然后我将 bound_lower 和 bound_upper 的移位移到循环的前面,因为我已经有了初始范围。
  4. 我将 attr.keys() 转换为一个元组,以便它可以被索引。事实上,那是失败的。