如何使用 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
How to get LDAP groups name using Oracle dbms_ldap package?
提问by sergdenisov
I used this example and successfully connected to LDAP
server - 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:
我得到了这个结果:
Actually, the user have 3 groups, but one group is
Primary
and 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 memberOf
attribute) 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)组件。