Cómo utilizar LDAP con ORACLE PLSQL

 Hola Amig@s,

Si queremos validar un usuario AD (usuario de directorio activo) utilizando Oracle PLSQL podemos hacerlo mediante ciertas funciones que tiene el paquete DBMS_LDAP.

Lo bueno de este sistema es que tendremos la gestión de todos los usuarios desde un solo sitio, es decir desde el AD. Esto normalmente se conoce como SSO o Single Sign On. Hay varias formas de validar Oracle contra un AD, una es LDAP, otra es ADFS.

En este artículo trataremos la forma de hacerlo con LDAP.

Lo primero es crear la ACL para el servidor AD.

BEGIN

 DBMS_NETWORK_ACL_ADMIN.create_acl (acl          => 'a.xml',

 description  => 'Regla para permitir la conexión a un servidor externo',principal    => 'USER', --Aquí va el usuario del esquema en el que queremos activarlois_grant     => TRUE,

 privilege    => 'connect',

 start_date   => SYSTIMESTAMP,

 end_date     => NULL);

 DBMS_NETWORK_ACL_ADMIN.add_privilege (acl         => 'a.xml',

 principal   => 'USER', --Aquí va el usuario del esquema en el que queremos activarlois_grant    => TRUE,

 privilege   => 'resolve',

 position    => NULL,

 start_date  => NULL,

 end_date    => NULL);

 DBMS_NETWORK_ACL_ADMIN.assign_acl (acl         => 'a.xml',

 host        => '192.168.1.215', --Aquí va el servidor al que debemos dar paso para el usuario de bbdd.

 lower_port  => 389, --Aquí definimos el puerto inicial o si lo ponemos a null todos los puertos son validos.

 upper_port  => NULL); --Aquí si va a NULL se toma como limite el puerto lower.

 COMMIT;

 END;

Recuerden que deben reemplazar el host y el USER por vuestra configuración.

Ahora bien, el siguiente código, es un ejemplo que al ejecutarlo, devolverá toda la información relacionada con el usuario.

El código no es mío, está basado en el disponible en Oracle Base https://oracle-base.com/articles/9i/ldap-from-plsql-9i solo lo he modificado un poco para adaptarlo a la prueba.

DECLARE

  -- Adjust as necessary.

  l_ldap_host    VARCHAR2(256) := '192.168.1.215';

  l_ldap_port    VARCHAR2(256) := '389'; --cuidado hay que crear la acl.

  l_ldap_user    VARCHAR2(256) := 'prueba@TESTAD.local'; --usuario de prueba del dominio

  l_ldap_passwd  VARCHAR2(256) := 'prueba456';  

  l_ldap_base    VARCHAR2(256) := 'CN=Users,DC=TESTAD,DC=local';

  l_userinfo     VARCHAR2(256) := 'prueba'; --usuario para el filtro


  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;

  --esto es importante, sino devuelve un ora-12703

  DBMS_LDAP.UTF8_CONVERSION := false;


  -- 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 

  -- para ver todos los atributos, mirar aqui. https://www.manageengine.com/products/ad-manager/help/csv-import-management/active-directory-ldap-attributes.html

  l_retval := DBMS_LDAP.search_s(ld       => l_session, 

                                 base     => l_ldap_base, 

                                 scope    => DBMS_LDAP.SCOPE_SUBTREE,

                                 filter   => 'sAMAccountName='||l_userinfo,

                                 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;

/

Como podrán ver lo que estamos haciendo es consultar contra el AD si el usuario prueba existe, si existe devolverá toda la información referente al usuario.

La salida del dbms output será similar a esta:

ATTIBUTE_NAME: objectClass = top

ATTIBUTE_NAME: objectClass = person

ATTIBUTE_NAME: objectClass = organizationalPerson

ATTIBUTE_NAME: objectClass = user

ATTIBUTE_NAME: cn = Usuario de Prueba

ATTIBUTE_NAME: sn = -

ATTIBUTE_NAME: description = Usuario de prueba para ver si se comunica con Oracle

ATTIBUTE_NAME: physicalDeliveryOfficeName = Laguna del marquez de bravia

ATTIBUTE_NAME: givenName = Usuario

ATTIBUTE_NAME: displayName = Usuario de Pruebaa

ATTIBUTE_NAME: uSNCreated = 12755

ATTIBUTE_NAME: memberOf = CN=Remote Desktop Users,CN=Builtin,DC=TESTAD,DC=local

ATTIBUTE_NAME: memberOf = CN=Users,CN=Builtin,DC=TESTAD,DC=local

ATTIBUTE_NAME: uSNChanged = 12798

ATTIBUTE_NAME: streetAddress = aqui mismo

...

Et voila!

Ya tenemos iteracción con un AD desde Oracle Plsql. Con esta información luego se puede establecer un sistema de validación, básicamente buscando una propiedad y comparándola.

Espero que les haya resultado útil.

Share on Google Plus
    Blogger Comment

0 comentarios: