semi OT - Anonymous authentication against AD using DBMS_LDAP

From: Guillermo Alan Bort <cicciuxdba_at_gmail.com>
Date: Wed, 11 Jan 2012 15:51:04 -0300
Message-ID: <CAJ2dSGTd-9QdVvbNaS9P344W-ckpx=g8sAukBca2XtDEc=g=nA_at_mail.gmail.com>



I am working on a pet project that aims to ease my job a lot, but it requires getting information from Active Directory. Using my own DN (which was easy enough to find out) I was able to log on to the AD and query just about any information I wanted. However now I'm facing the problem of authenticating the application using LDAP. The problem here is that the sAMAccountName (which is what people usually use to log on to all the apps as well as their laptops) is different from the CN in the DN. And as far as my testing (and a few hours of google searches) I have to provide the DN in order to authenticate.
I have tried setting the username and password fields to null in dbms_ldap.simple_bind_s but it does not appear to work. The retval is 0 but when I try to execute the dbms_ldap.search_s in order to get the DN based on the sAMAccountName I get the following error:

ORA-31202: DBMS_LDAP: LDAP client/server error: Operations error. 000004DC: LdapErr: DSID-0C0906DC, comment: In order to perform this operation a successful bind must be completed on the connection., data 0, v1db0

ORA-06512: at "SYS.DBMS_SYS_ERROR", line 86
ORA-06512: at "SYS.DBMS_LDAP", line 1487
ORA-06512: at "SYS.DBMS_LDAP", line 234

Database version is 11.2.0.2

I am guessing the problem si that AD has anonymous authentication disabled, but I'd like some confirmation. I am using code I got from ORACLE-BASE as it's the easiest test I could find:

SET SERVEROUTPUT ON SIZE 1000000
DECLARE

  • Adjust as necessary. l_ldap_host VARCHAR2(256) := 'ad.company.com'; l_ldap_port VARCHAR2(256) := '389'; l_ldap_base VARCHAR2(256) := 'DC­,DC=company,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; l_retval := 1; dbms_output.put_line ('PRE Connected: ' || l_retval);
  • 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     => NULL,
                                      passwd => NULL );

  dbms_output.put_line ('Connected: ' || l_retval);

  • Get all attributes l_attrs(1) := 'distinguishedName'; -- retrieve all attributes l_retval := DBMS_LDAP.search_s(ld => l_session, base => l_ldap_base, scope => DBMS_LDAP.SCOPE_SUBTREE, filter => 'sAMAccountName=<somethings>', 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 also tried using bind_s (instead of simple_bind_s)

   l_retval := DBMS_LDAP.bind_s(ld     => l_session,
                                      dn     => NULL,
                                      cred => NULL,
                                      meth => DBMS_LDAP.AUTH_SIMPLE );

but according to the documentation AUTH_SIMPLE is the only method supported by the function ¬¬

Any help will be appreciated.

On another (side)note I am also thinking of using AD for APEX authentication, but I'm facing the same issue of people using the sAMAccountName instead of the DN, any ideas for this one?

Thank you very much
Alan.-

--
http://www.freelists.org/webpage/oracle-l
Received on Wed Jan 11 2012 - 12:51:04 CST

Original text of this message