Как с помощью DBMS_LDAP получить email пользователя AD?

Trust
Дата: 29.07.2005 12:50:51
Кому - нить приходилось интегрироваться с АД.
Я обращаюсь из процедуры к АД используя скрипт-
http://www.oracle-base.com/articles/9i/LDAPFromPLSQL9i.php

Проблема в том, что таким образом можно получить только аттрибуты Name, distinguishedName и др. служебные. А кто знает как получить telephonenumber, phone, email, title?
Trust
Дата: 29.07.2005 15:17:10
Может у кого хотя бы какие-нить идеи есть..
Подскажите хотя бы, еще форум на котором можно спросить.
vitalych
Дата: 31.07.2005 13:08:46
Trust
Может у кого хотя бы какие-нить идеи есть..
Подскажите хотя бы, еще форум на котором можно спросить.

лучший форум по оракле
l_kator
Дата: 04.12.2008 18:24:16
в развитие темы: где взять список аттрибутов для функции DBMS_LDAP.get_values ?
Андрей Панфилов
Дата: 04.12.2008 20:54:37
l_kator
в развитие темы: где взять список аттрибутов для функции DBMS_LDAP.get_values ?


для того чтобы вытянуть атрибуты ldap достаточно занать корень:

dn: CN=Organizational-Person,CN=Schema,CN=Configuration,DC=domain
changetype: add
objectClass: top
objectClass: classSchema
cn: Organizational-Person
distinguishedName:
CN=Organizational-Person,CN=Schema,CN=Configuration,DC=domain
instanceType: 4
whenCreated: 16301021162111.0Z
whenChanged: 20070907074308.0Z
uSNCreated: 6733
subClassOf: person
governsID: 2.5.6.7
mayContain: houseIdentifier
mayContain: homePostalAddress
mayContain: employeeNumber
mayContain: personalPager
mayContain: telephoneAssistant
mayContain: msExchHouseIdentifier
mayContain: businessRoles
mayContain: employeeType
rDNAttID: cn
uSNChanged: 6733
showInAdvancedViewOnly: TRUE
adminDisplayName: Organizational-Person
adminDescription: Organizational-Person
objectClassCategory: 0
lDAPDisplayName: organizationalPerson
name: Organizational-Person
systemOnly: FALSE
systemPossSuperiors: organizationalUnit
systemPossSuperiors: organization
systemPossSuperiors: container
systemMayContain: msDS-AllowedToDelegateTo
systemMayContain: x121Address
systemMayContain: comment
systemMayContain: title
systemMayContain: co
systemMayContain: primaryTelexNumber
systemMayContain: telexNumber
systemMayContain: teletexTerminalIdentifier
systemMayContain: street
systemMayContain: st
systemMayContain: registeredAddress
systemMayContain: preferredDeliveryMethod
systemMayContain: postalCode
systemMayContain: postalAddress
systemMayContain: postOfficeBox
systemMayContain: thumbnailPhoto
l_kator
Дата: 05.12.2008 10:14:04
Андрей Панфилов,
Этот список вы как получили?
Может, совсем тупые вопросы задаю, но как же получить инфу о пользователе? Полную инфу, хранящуюся где-то в ЛДАП. Надо очень быстро сделать, вся надежда на форум
Андрей Панфилов
Дата: 05.12.2008 13:08:32
l_kator,

я не знаю как работает DMBS_LDAP в оракле, но знаю как устроен сам LDAP:
у каждой записи есть атрибут objectClass (или несколько), objectClass описывает атрибуты которые могут присутствовать в записи LDAP и которые должны присутствовать, список этих атрибутов описывает так же в LDAP, в том примере что привел я указан список атрибутов для objectClass Organizational-Person (CN=Organizational-Person,CN=Schema,CN=Configuration,DC=domain - так в AD, в другом LDAP ветка может быть другой).
т.е. алгоритм простой:
найти запись по фильтру (либо обратиться к ней), узнать какие objectClass у записи, для каждого objectClass определить список атрибутов, по списку атрибутов определить их значения у записи.
Андрей Панфилов
Дата: 05.12.2008 13:18:21
Андрей Панфилов,

вообще чтобы отлаживаться воспользуйтесь либо консольной утилитой ldifde, либо jexplorer (http://www.jxplorer.org/), в остнаске MS тоже есть какая-то тула для работы с ldap.
iehf
Дата: 05.12.2008 14:14:41
l_kator,

может это поможет (тестировал на OID 9i). Код писАл для себя - строго не судить

set serveroutput on size 30000

create or replace procedure testsearch 
as 
retval       PLS_INTEGER;
my_session   DBMS_LDAP.session;
my_attrs     DBMS_LDAP.string_collection;
my_message   DBMS_LDAP.message;
my_entry     DBMS_LDAP.message;
entry_index  PLS_INTEGER;
my_dn        VARCHAR2(256);
my_attr_name VARCHAR2(256);
my_ber_elmt  DBMS_LDAP.ber_element;
attr_index   PLS_INTEGER;
i          PLS_INTEGER;
my_vals DBMS_LDAP.STRING_COLLECTION ;
ldap_host  VARCHAR2(256);
ldap_port  VARCHAR2(256);
ldap_user  VARCHAR2(256);
ldap_passwd  VARCHAR2(256);
ldap_base  VARCHAR2(256);

BEGIN 
retval         := -1;
   
-- здесь настроить как надо
ldap_host  := 'ora' ; -- хост оида
ldap_port  := '389'; -- порт оида
ldap_user  := 'cn=orcladmin'; -- пользователь
ldap_passwd:= 'welcome'; -- его пароль
ldap_base  := 'cn=scott,cn=users,dc=ora,dc=com'; -- dn пользователя для которого ищутся атрибуты


 DBMS_OUTPUT.PUT('DBMS_LDAP Search Example ');
 DBMS_OUTPUT.PUT_LINE('to directory .. ');
 DBMS_OUTPUT.PUT_LINE(RPAD('LDAP Host ',25,' ') || ': ' || ldap_host);
 DBMS_OUTPUT.PUT_LINE(RPAD('LDAP Port ',25,' ') || ': ' || ldap_port);

 -- используется механизм исключений.
 DBMS_LDAP.USE_EXCEPTION := TRUE;
 my_session := DBMS_LDAP.init(ldap_host,ldap_port);
 
 DBMS_OUTPUT.PUT_LINE (RPAD('Сессия ',25,' ')  || ': ' ||RAWTOHEX(SUBSTR(my_session,1,8)) || '(из init)');

 -- бинд к каталогу
 retval := DBMS_LDAP.simple_bind_s(my_session,ldap_user, ldap_passwd);
 
 DBMS_OUTPUT.PUT_LINE(RPAD('из simplebind ',25,' ') || ': '|| TO_CHAR(retval));
 
 -- ищем
 my_attrs(1) := 'mail'; -- если надо конкретно мыло, или еще чего. Если все - то '*' 
 retval := DBMS_LDAP.search_s(my_session, ldap_base, 
                              DBMS_LDAP.SCOPE_BASE,
                              'objectclass=*',
                              my_attrs,
                              0,
                              my_message);

 DBMS_OUTPUT.PUT_LINE(RPAD('из search_s ',25,' ') || ': '|| TO_CHAR(retval));
 DBMS_OUTPUT.PUT_LINE (RPAD('сообщение  ',25,' ')  || ': ' || RAWTOHEX(SUBSTR(my_message,1,8)) ||'(из search_s)');

 -- найдено
 retval := DBMS_LDAP.count_entries(my_session, my_message);
 DBMS_OUTPUT.PUT_LINE(RPAD('Записей ',25,' ') || ': '|| TO_CHAR(retval));
 DBMS_OUTPUT.PUT_LINE('---------------------------------------------------');
 -- начало
 my_entry := DBMS_LDAP.first_entry(my_session, my_message);
 entry_index := 1;

 -- цикл по каждому элементу
 while my_entry IS NOT NULL loop

   -- текущее вхождение
   my_dn := DBMS_LDAP.get_dn(my_session, my_entry);
   DBMS_OUTPUT.PUT_LINE ('        dn: ' || my_dn); 
   my_attr_name := DBMS_LDAP.first_attribute(my_session,my_entry,my_ber_elmt);
   attr_index := 1;
   while my_attr_name IS NOT NULL loop

     my_vals := DBMS_LDAP.get_values (my_session, my_entry,my_attr_name);
     if my_vals.COUNT > 0 then
       FOR i in my_vals.FIRST..my_vals.LAST loop
	  DBMS_OUTPUT.PUT_LINE('Найдено      ' || my_attr_name || ' : ' || SUBSTR(my_vals(i),1,200));
       end loop;    
     end if;
     my_attr_name := DBMS_LDAP.next_attribute(my_session,my_entry,my_ber_elmt);
     attr_index := attr_index+1;
--
   end loop;
   my_entry := DBMS_LDAP.next_entry(my_session, my_entry);
   DBMS_OUTPUT.PUT_LINE('===================================================');
   entry_index := entry_index+1;

end loop; 
   retval := DBMS_LDAP.unbind_s(my_session); 
   DBMS_OUTPUT.PUT_LINE(RPAD('unbind_res вернул ',25,' ') || ': ' || TO_CHAR(retval)); DBMS_OUTPUT.PUT_LINE('ОК'); 
-- Exceptions 
EXCEPTION

WHEN OTHERS THEN

   DBMS_OUTPUT.PUT_LINE(' Error code    : ' || TO_CHAR(SQLCODE));
   DBMS_OUTPUT.PUT_LINE(' Error Message : ' || SQLERRM);
   DBMS_OUTPUT.PUT_LINE(' Выход по ошибке');

END;
/