Oracle® Internet Directory Administrator's Guide 10g (9.0.4) Part Number B12118-01 |
|
Setting Up the Customized External Authentication Plug-in, 3 of 3
This section contains these topics:
This example uses the a PL/SQL program, oidexaup.sql
, which is described in "Contents of PL/SQL Package oidexaup.sql". This package is used for installing the external authentication plug-in PL/SQL package. It contains two plug-ins--namely, when_compare_replace
and when_modify_replace
--and one utility function --namely, get_nickname
. The integrated package is the plug-in package, OIDEXTAUTH
. This package can also serve as a template you to modify according to your deployment environment.
To install, configure, and enable the external authentication plug-in, follow these steps:
In our sample code, oidexaup.sql
, auth_external
is the program package name, and authenticate_user
is the function that does the authentication. You need to make sure that this standalone program is working properly before you move on to next steps.
sqlplus ods/odspwd @oidexaup.sql
dn: cn=whencompare,cn=plugin,cn=subconfigsubentry objectclass:orclPluginConfig objectclass:top orclpluginname:oidextauth orclplugintype:operational orclplugintiming:when orclpluginldapoperation:ldapcompare orclpluginenable:1 orclpluginversion:1.0.1 orclPluginIsReplace:1 cn:whencompare orclpluginsubscriberdnlist:dc=com;o=IMC,c=US orclpluginattributelist:userpassword orclpluginrequestgroup:$prgdn dn: cn=whenmodify,cn=plugin,cn=subconfigsubentry objectclass:orclPluginConfig objectclass:top orclpluginname:oidextauth orclplugintype:operational orclplugintiming:when orclpluginldapoperation:ldapmodify orclpluginenable:1 orclpluginversion:1.0.1 orclPluginIsReplace:1 cn:whenmodify orclpluginsubscriberdnlist:dc=com;o=IMC,c=US orclpluginattributelist:userpassword orclpluginrequestgroup:$prgdn
In this file, we notify the directory server that, whenever there is an ldapcompare or ldapmodify request, there are two plug-ins to be invoked.
We use orclpluginsubscriberdnlist:dc=com;o=IMC,c=US
so that plug-ins will ONLY be invoked if the target entry is under dc=com
or o=IMC,c=US
.
Replace $prgdn
with the plug-in request group DN. This is an optional, recommended security feature. For integrating with Oracle Application Server Single Sign-On, this value is a required field. Only members of the group entered can invoke the plug-ins. You may enter multiple groups. Use a semicolon to separate entries.
The recommended defaults are: cn=OracleUserSecurityAdmins,cn=Groups,cn=OracleContext
and cn=OracleDASAdminGroup,cn=Groups,cn=OracleContext,
. Note that the Oracle Application Server Single Sign-On server is a member of the first group. Also, be sure to replace
o=default_subscriber,dc=como=default_subscriber
with the correct value for your deployment environment.
To add this file to the directory, enter the following:
ldapadd -p portnum -h hostname -D cn=orcladmin -w orcladminpwd -v -f oidexauth.ldif
Now, everything should be ready. Use the ldapcompare command-line tool to verify that the plug-in and authentication program are working properly before you try to authenticate user from Oracle Application Server Single Sign-On.
In our example, we also provide the plug-in code for externally modifying user password.
Turn on directory server plug-in to help you to examine the process and content of plug-ins.
To setup directory server plug-in debugging, execute the following command:
sqlplus ods/password @$ORACLE/ldap/admin/oidspdsu.sql
To enable directory server plug-in debugging, execute the following command:
sqlplus ods/password @$ORACLE/ldap/admin/oidspdon.sql
To disable directory server plug-in debugging, execute the following command:
sqlplus ods/password @$ORACLE/ldap/admin/oidspdof.sql
To show directory server plug-in debugging messages, execute the following command:
sqlplus ods/password @$ORACLE/ldap/admin/oidspdsh.sql
To delete directory server plug-in debugging messages, please execute the following command:
sqlplus ods/password @$ORACLE/ldap/admin/oidspdde.sql
The script oidexaup.sql, as used in this example, contains the following:
CREATE OR REPLACE PACKAGE OIDEXTAUTH AS PROCEDURE when_compare_replace (ldapplugincontext IN ODS.plugincontext, result OUT INTEGER, dn IN VARCHAR2, attrname IN VARCHAR2, attrval IN VARCHAR2, rc OUT INTEGER, errormsg OUT VARCHAR2 ); PROCEDURE when_modify_replace (ldapplugincontext IN ODS.plugincontext, dn IN VARCHAR2, mods IN ODS.modlist, rc OUT INTEGER, errormsg OUT VARCHAR2 ); FUNCTION get_nickname (dn IN VARCHAR2, my_session IN DBMS_LDAP.session) RETURN VARCHAR2; END OIDEXTAUTH; / SHOW ERROR CREATE OR REPLACE PACKAGE BODY OIDEXTAUTH AS -- We use this function to convert the dn to nickname. -- When OID server receives the ldapcompare request, it -- only has the dn information. We need to use DBMS_LDAP_UTL -- package to find out the nickname attribute value of -- the entry. FUNCTION get_nickname (dn IN VARCHAR2, my_session IN DBMS_LDAP.session) RETURN VARCHAR2 IS my_pset_coll DBMS_LDAP_UTL.PROPERTY_SET_COLLECTION; my_property_names DBMS_LDAP.STRING_COLLECTION; my_property_values DBMS_LDAP.STRING_COLLECTION; user_handle DBMS_LDAP_UTL.HANDLE; user_id VARCHAR2(2000); user_type PLS_INTEGER; user_nickname VARCHAR2(256) DEFAULT NULL; my_attrs DBMS_LDAP.STRING_COLLECTION; retval PLS_INTEGER; BEGIN plg_debug( '=== Beginning of get_nickname() === '); user_type := DBMS_LDAP_UTL.TYPE_DN; user_id := dn; retval := DBMS_LDAP_UTL.create_user_handle(user_handle, user_type, user_ id); plg_debug( 'create_user_handle() Returns ' || To_char(retval)); retval := DBMS_LDAP_UTL.get_user_properties(my_session, user_handle, my_attrs, DBMS_LDAP_UTL.NICKNAME_ PROPERTY, my_pset_coll); plg_debug( 'get_user_properties() Returns ' || To_char(retval)); IF my_pset_coll.COUNT > 0 THEN FOR i IN my_pset_coll.first .. my_pset_coll.last LOOP retval := DBMS_LDAP_UTL.get_property_names(my_pset_coll(i), my_property_names); IF my_property_names.COUNT > 0 THEN FOR j IN my_property_names.first .. my_property_names.last LOOP retval := DBMS_LDAP_UTL.get_property_values(my_pset_coll(i), my_property_ names(j), my_property_ values); IF my_property_values.COUNT > 0 THEN FOR k IN my_property_values.FIRST..my_property_values.LAST LOOP user_nickname := my_property_values(k); plg_debug( 'user nickname = ' || user_nickname); END LOOP; END IF; END LOOP; END IF; -- IF my_property_names.count > 0 END LOOP; END IF; -- If my_pset_coll.count > 0 plg_debug( 'got user_nickname: ' || user_nickname); -- Free my_properties IF my_pset_coll.count > 0 then DBMS_LDAP_UTL.free_propertyset_collection(my_pset_coll); END IF; DBMS_LDAP_UTL.free_handle(user_handle); RETURN user_nickname; EXCEPTION WHEN OTHERS THEN plg_debug('Exception in get_nickname. Error code is ' || to_ char(sqlcode)); plg_debug(' ' || Sqlerrm); RETURN NULL; END; PROCEDURE when_compare_replace (ldapplugincontext IN ODS.plugincontext, result OUT INTEGER, dn IN VARCHAR2, attrname IN VARCHAR2, attrval IN VARCHAR2, rc OUT INTEGER, errormsg OUT VARCHAR2 ) IS retval pls_integer; lresult BOOLEAN; my_session DBMS_LDAP.session; my_property_names DBMS_LDAP.STRING_COLLECTION; my_property_values DBMS_LDAP.STRING_COLLECTION; my_attrs DBMS_LDAP.STRING_COLLECTION; my_pset_coll DBMS_LDAP_UTL.PROPERTY_SET_COLLECTION; user_handle DBMS_LDAP_UTL.HANDLE; user_id VARCHAR2(2000); user_type PLS_INTEGER; user_nickname VARCHAR2(60); remote_dn VARCHAR2(256); i PLS_INTEGER; j PLS_INTEGER; k PLS_INTEGER; BEGIN plg_debug( '=== Begin of WHEN-COMPARE-REPLACE plug-in'); plg_debug( 'DN = ' || dn); plg_debug( 'Attr = ' || attrname); --plg_debug( 'Attrval = ' || attrval); DBMS_LDAP.USE_EXCEPTION := FALSE; errormsg := 'No error msg'; rc := 0; -- converting dn to nickname my_session := LDAP_PLUGIN.init(ldapplugincontext); plg_debug( 'ldap_session =' || RAWTOHEX(SUBSTR(my_session,1,8))); retval := LDAP_PLUGIN.simple_bind_s(ldapplugincontext, my_session); plg_debug( 'simple_bind_res =' || TO_CHAR(retval)); user_nickname := get_nickname(dn, my_session); plg_debug( 'user_nickname =' || user_nickname); -- unbind from the directory retval := DBMS_LDAP.unbind_s(my_session); plg_debug( 'unbind_res Returns ' || To_char(retval)); IF (user_nickname IS NULL) THEN result := 32; errormsg := 'Can''t find the nickname'; plg_debug( 'Can''t find the nickname'); RETURN; END IF; plg_debug( '=== Now go to extauth '); BEGIN retval := auth_external.authenticate_user(user_nickname, attrval); plg_debug( 'auth_external.authenticate_user() returns = ' || 'True'); result := 6; -- compare result is TRUE EXCEPTION WHEN OTHERS THEN result := 5; -- compare result is FALSE plg_debug( 'auth_external.authenticate_user() returns = ' || 'False'); RETURN; END; plg_debug( '=== End of WHEN-COMPARE-REPLACE plug-in'); EXCEPTION WHEN OTHERS THEN rc := 1; errormsg := 'Exception: when_compare_replace plugin'; plg_debug( 'EXCEPTION: ' || retval); plg_debug('Exception in when_compare. Error code is ' || to_ char(sqlcode)); plg_debug(' ' || Sqlerrm); END; PROCEDURE when_modify_replace (ldapplugincontext IN ODS.plugincontext, dn IN VARCHAR2, mods IN ODS.modlist, rc OUT INTEGER, errormsg OUT VARCHAR2 ) IS retval pls_integer; lresult BOOLEAN; my_session DBMS_LDAP.SESSION; my_property_names DBMS_LDAP.STRING_COLLECTION; my_property_values DBMS_LDAP.STRING_COLLECTION; my_attrs DBMS_LDAP.STRING_COLLECTION; my_modval DBMS_LDAP.BERVAL_COLLECTION; my_pset_coll DBMS_LDAP_UTL.PROPERTY_SET_COLLECTION; user_handle DBMS_LDAP_UTL.HANDLE; l_mod_array RAW(32); user_id VARCHAR2(2000); user_type PLS_INTEGER; user_nickname VARCHAR2(2000); old_passwd VARCHAR2(60) DEFAULT NULL; new_passwd VARCHAR2(60) DEFAULT NULL; remote_dn VARCHAR2(256); i PLS_INTEGER; j PLS_INTEGER; k PLS_INTEGER; BEGIN plg_debug( '=== Begin of WHEN-MODIFY-REPLACE plug-in'); DBMS_LDAP.USE_EXCEPTION := FALSE; user_type := DBMS_LDAP_UTL.TYPE_DN; user_id := dn; -- converting dn to nickname my_session := LDAP_PLUGIN.init(ldapplugincontext); plg_debug( 'ldap_session =' || RAWTOHEX(SUBSTR(my_session,1,8))); retval := LDAP_PLUGIN.simple_bind_s(ldapplugincontext, my_session); plg_debug( 'simple_bind_res =' || TO_CHAR(retval)); user_nickname := get_nickname(dn, my_session); plg_debug( 'user_nickname =' || user_nickname); -- unbind from the directory retval := DBMS_LDAP.unbind_s(my_session); FOR l_counter1 IN 1..mods.COUNT LOOP IF (mods(l_counter1).operation = 2) AND (mods(l_counter1).type = 'userpassword') THEN FOR l_counter2 IN 1..mods(l_counter1).vals.COUNT LOOP new_passwd := mods(l_counter1).vals(l_counter2).val; END LOOP; END IF; IF (mods(l_counter1).operation = 0) AND (mods(l_counter1).type = 'userpassword') THEN FOR l_counter2 IN 1..mods(l_counter1).vals.COUNT LOOP new_passwd := mods(l_counter1).vals(l_counter2).val; END LOOP; END IF; IF (mods(l_counter1).operation = 1) AND (mods(l_counter1).type = 'userpassword') THEN FOR l_counter2 IN 1..mods(l_counter1).vals.COUNT LOOP old_passwd := mods(l_counter1).vals(l_counter2).val; END LOOP; END IF; END LOOP; IF new_passwd IS NOT NULL AND old_passwd IS NOT NULL THEN BEGIN auth_external.change_passwd(user_nickname, old_passwd, new_passwd); EXCEPTION WHEN OTHERS THEN rc := 1; plg_debug( 'auth_external.change_passwd() raised exception.'); errormsg := 'auth_external.change_passwd() raised exception.'; RETURN; END; ELSIF new_passwd IS NOT NULL AND old_passwd IS NULL THEN BEGIN auth_external.reset_passwd(user_nickname, new_passwd); EXCEPTION WHEN OTHERS THEN plg_debug( 'auth_external.reset_passwd() raised exception.'); rc := 1; errormsg := 'auth_external.reset_passwd() raised exception.'; RETURN; END; ELSE rc := 1; errormsg := 'PLG_Exception. Not enough info to change passwd.'; END IF; plg_debug( 'external change password succeed'); rc := 0; errormsg := 'No when_mod_replace plguin error msg'; retval := DBMS_LDAP.unbind_s(my_session); plg_debug( 'End of WHEN-MODIFY-REPLACE'); --COMMIT; EXCEPTION WHEN others THEN rc := 1; errormsg := 'PLG_Exception: when_modify_replace plguin'; plg_debug('Exception in when_modify. Error code is ' || to_ char(sqlcode)); plg_debug(' ' || Sqlerrm); END; END OIDEXTAUTH; / SHOW ERRORS --list GRANT EXECUTE ON OIDEXTAUTH TO ods_server; EXIT;
|
![]() Copyright © 1999, 2003 Oracle Corporation. All Rights Reserved. |
|