如何使用 Oracle dbms_ldap 包获取 LDAP 组名称?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19254308/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-19 01:59:35  来源:igfitidea点击:

How to get LDAP groups name using Oracle dbms_ldap package?

oracleplsqloracle11gldap

提问by sergdenisov

I used this example and successfully connected to LDAPserver - http://www.oracle-base.com/articles/9i/ldap-from-plsql-9i.php.

我使用了这个例子并成功连接到LDAP服务器 - http://www.oracle-base.com/articles/9i/ldap-from-plsql-9i.php

SET SERVEROUTPUT ON SIZE 1000000
DECLARE
  -- Adjust as necessary.
  l_ldap_host    VARCHAR2(256) := 'server01.tshcomputing.com';
  l_ldap_port    VARCHAR2(256) := '389';
  l_ldap_user    VARCHAR2(256) := 'cn=orcladmin';
  l_ldap_passwd  VARCHAR2(256) := 'password';
  l_ldap_base    VARCHAR2(256) := 'cn=Users,dc=tshcomputing,dc=com';

  l_retval       PLS_INTEGER; 
  l_session      DBMS_LDAP.session;
  l_attrs        DBMS_LDAP.string_collection;
  l_message      DBMS_LDAP.message;
  l_entry        DBMS_LDAP.message;
  l_attr_name    VARCHAR2(256);
  l_ber_element  DBMS_LDAP.ber_element;
  l_vals         DBMS_LDAP.string_collection;

BEGIN
  -- Choose to raise exceptions.
  DBMS_LDAP.USE_EXCEPTION := TRUE;

  -- Connect to the LDAP server.
  l_session := DBMS_LDAP.init(hostname => l_ldap_host,
                              portnum  => l_ldap_port);

  l_retval := DBMS_LDAP.simple_bind_s(ld     => l_session,
                                      dn     => l_ldap_user,
                                      passwd => l_ldap_passwd);

  -- Get all attributes
  l_attrs(1) := '*'; -- retrieve all attributes 
  l_retval := DBMS_LDAP.search_s(ld       => l_session, 
                                 base     => l_ldap_base, 
                                 scope    => DBMS_LDAP.SCOPE_SUBTREE,
                                 filter   => 'objectclass=*',
                                 attrs    => l_attrs,
                                 attronly => 0,
                                 res      => l_message);

  IF DBMS_LDAP.count_entries(ld => l_session, msg => l_message) > 0 THEN
    -- Get all the entries returned by our search.
    l_entry := DBMS_LDAP.first_entry(ld  => l_session,
                                     msg => l_message);

    << entry_loop >>
    WHILE l_entry IS NOT NULL LOOP
      -- Get all the attributes for this entry.
      DBMS_OUTPUT.PUT_LINE('---------------------------------------');
      l_attr_name := DBMS_LDAP.first_attribute(ld        => l_session,
                                               ldapentry => l_entry,
                                               ber_elem  => l_ber_element);
      << attributes_loop >>
      WHILE l_attr_name IS NOT NULL LOOP
        -- Get all the values for this attribute.
        l_vals := DBMS_LDAP.get_values (ld        => l_session,
                                        ldapentry => l_entry,
                                        attr      => l_attr_name);
        << values_loop >>
        FOR i IN l_vals.FIRST .. l_vals.LAST LOOP
          DBMS_OUTPUT.PUT_LINE('ATTIBUTE_NAME: ' || l_attr_name || ' = ' || SUBSTR(l_vals(i),1,200));
        END LOOP values_loop;
        l_attr_name := DBMS_LDAP.next_attribute(ld        => l_session,
                                                ldapentry => l_entry,
                                                ber_elem  => l_ber_element);
      END LOOP attibutes_loop;
      l_entry := DBMS_LDAP.next_entry(ld  => l_session,
                                      msg => l_entry);
    END LOOP entry_loop;
  END IF;

  -- Disconnect from the LDAP server.
  l_retval := DBMS_LDAP.unbind_s(ld => l_session);
  DBMS_OUTPUT.PUT_LINE('L_RETVAL: ' || l_retval);
END;
/

I got this this result:

我得到了这个结果:

ResultsActually, the user have 3 groups, but one group is Primaryand stored in primaryGroupID. I tried to do queries for groups, but I couldn't find attribute like ID. How can I get groups info (like a value of memberOfattribute) by primaryGroupID?

结果实际上,用户有 3 个组,但其中一组Primary存储在primaryGroupID. 我尝试对组进行查询,但找不到 ID 之类的属性。如何通过 获取组信息(如memberOf属性值)primaryGroupID

回答by Justin

As annoying as it may be, this is necessarily a two-part process. memberOf (and LDAP multip-valued attribute) stores all the group memberships exceptthe primaryGroup membership, which is stored in a completely different way, as you have discovered. The key is the "primaryGroupToken" attribute of group objects, which correlates to the primaryGroupID of users.

尽管可能很烦人,但这必然是一个由两部分组成的过程。memberOf(和LDAP 多值属性)存储primaryGroup 成员身份之外的所有组成员身份,正如您所发现的,primaryGroup 成员身份以完全不同的方式存储。关键是组对象的“primaryGroupToken”属性,与用户的primaryGroupID相关。

I was doing the reverse, so as a service to myself, made my own function that will give the primaryGroup ID value/"token":

我正在做相反的事情,因此作为对自己的服务,我制作了自己的函数,该函数将提供 primaryGroup ID 值/“令牌”:

   --Special from of group membership not appearing in the memberof attribute.
   --Function accepts (flexibly) a SID or a group name and return the token that  
   --would be stored in the attribute "primaryGroupID" of a user object.
FUNCTION get_primaryGroupToken(p_sid_samid IN VARCHAR2) RETURN VARCHAR2 IS
  l_retval PLS_INTEGER;
  l_attrs dbms_ldap.string_collection;
  l_message dbms_ldap.message;
  l_entry dbms_ldap.message;
  l_attr_name VARCHAR2(256);
  l_ber_element dbms_ldap.ber_element;
  l_vals dbms_ldap.string_collection;
  l_primaryGroupToken VARCHAR2(256) := NULL;
  l_filter            VARCHAR2(256);
BEGIN
  IF SUBSTR( p_sid_samid, 2, 1 ) = '-' THEN
    dbms_output.put_line('group spec Is sid');
    l_filter := '(objectSid=' || p_sid_samid || ')';
  ELSE
    dbms_output.put_line('group spec Is samid');
    -- You could probably also use CN here instead of sAMAccountName
    l_filter := '(&(sAMAccountName=' || p_sid_samid || ')(objectClass=group))';
  END IF;
  l_retval   := get_ldap_session();
  l_attrs(1) := 'primaryGroupToken';
  l_retval   := DBMS_LDAP.search_s(ld => g_session, 
                    base => g_ldap_auth_base, 
                    scope => DBMS_LDAP.SCOPE_SUBTREE, 
                    filter => l_filter, 
                    attrs => l_attrs, 
                    attronly => 0, 
                    res => l_message);
  IF DBMS_LDAP.count_entries(ld => g_session, msg => l_message) > 0 THEN
    --Get all the entries returned by our search.
    l_entry := DBMS_LDAP.first_entry(ld => g_session,msg => l_message);
    <<entry_loop>>
    WHILE l_entry IS NOT NULL
    LOOP
      -- Get all the attributes for this entry.
      l_attr_name           := DBMS_LDAP.first_attribute(ld => g_session,ldapentry => l_entry, ber_elem => l_ber_element);
      IF lower(l_attr_name) <> 'primarygrouptoken' THEN
        DBMS_OUTPUT.PUT_LINE('ATTIBUTE_NAME unexpected : ' || l_attr_name );
      ELSE
        l_vals := DBMS_LDAP.get_values (ld => g_session, ldapentry => l_entry, attr => l_attr_name);
      END IF;
      << values_loop >>
      FOR i IN l_vals.FIRST .. l_vals.LAST
      LOOP
        l_primaryGroupToken := l_vals(i);
      END LOOP values_loop;
      IF l_primaryGroupToken IS NULL THEN
        l_attr_name          := DBMS_LDAP.next_attribute(ld => g_session, ldapentry => l_entry, ber_elem => l_ber_element);
        l_entry              := DBMS_LDAP.next_entry(ld => g_session,msg => l_entry);
      ELSE
        EXIT;
      END IF;
    END LOOP entry_loop;
  END IF;
  -- Disconnect from the LDAP server.
  l_retval := DBMS_LDAP.unbind_s(ld => g_session);
  RETURN l_primaryGroupToken;
END get_primaryGroupToken; 

Note that this function is in a package, and the "g_" variables are package globals. And of course eliminate the development only dbms_output calls, etc.

请注意,此函数在一个包中,“g_”变量是包全局变量。当然,消除仅开发 dbms_output 调用等。

Then I just did twofilter searches, one on primaryGroupID and one on memberOf to get allmembers of the group.

然后我只做了两个过滤器搜索,一个在 primaryGroupID 上,另一个在 memberOf 上,以获取组的所有成员。

In your case, just kinda to the reverse, have your own function that first evaluates all the memberOf values, then separately treat the primaryGroupToken with an LDAP search for the group with that primaryGroupToken.

在您的情况下,正好相反,拥有自己的函数,首先评估所有 memberOf 值,然后分别使用 LDAP 搜索具有该 primaryGroupToken 的组来处理 primaryGroupToken。

回答by geoffc

I thought there was an attribute holding that value on the group, but I am not seeing it.

我认为有一个属性在该组中保持该值,但我没有看到它。

Upon second thought, I think it is based on the RID component of the SID. You would have to parse the SID to get the RID (Relative ID) component.

再三考虑,我认为它是基于 SID 的 RID 组件。您必须解析 SID 才能获得 RID(相对 ID)组件。