Document-ID:        16365.1
Subject:            (V4/V45) CHANGING THE ORACLE PASSWORD IN ORACLE FORMS
Author:		     RMONGE
Last Modified Date: 06 March     1997


 

                How to Change the Oracle Password in Oracle Forms
                =================================================

Introduction
------------

The following bulletin discusses how to build a form that allows users
to change their individual database passwords.  This form can be executed
from a menu item type PL/SQL using the Call_Form or New_Form built-in.

Set-Up and Coding
-----------------

1. Create a new form Change_Password.

2. Create a non-base table block with three non-base table items:
   old_password, new_password, and retype_new_password.
   Set the following properties:

   Displayed            ON
   Insert_allowed       ON
   Update_allowed       ON
   Secure               ON
   Enabled              ON
   Navigable            ON
   Required             ON

The Secure property displays asterisks(*) when the user enters a value
on these fields, so no one can see the password.

                             ___________________
             OLD PASSWORD   |                   |
                             ___________________

                             ___________________
             NEW PASSWORD   |                   |
                             ___________________

                Retype
                             ___________________
             NEW PASSWORD   |                   |
                             ___________________

3. Create a button.
   The user can click on the button to change the password.
   Make the button only Mouse Navigable (turn Navigable OFF).

4. Create the following trigger on that button:

   WHEN-BUTTON-PRESSED-TRIGGER
   ===========================

    DECLARE
        UN  VARCHAR2(80);
        PW  VARCHAR2(80);
        CN  VARCHAR2(80);

    BEGIN
        UN := GET_APPLICATION_PROPERTY(USERNAME);
        PW := GET_APPLICATION_PROPERTY(PASSWORD);
        CN := GET_APPLICATION_PROPERTY(CONNECT_STRING);

        IF :BLOCK.OLD_PASSWORD IS NULL THEN
                BELL;
                MESSAGE ('PLEASE ENTER OLD PASSWORD ');
                MESSAGE(' ');
                GO_ITEM('BLOCK.OLD_PASSWORD');
                RAISE FORM_TRIGGER_FAILURE;
        END IF;

        IF :BLOCK.NEW_PASSWORD IS NULL THEN
                BELL;
                MESSAGE('PLEASE ENTER NEW PASSWORD. ');
                MESSAGE(' ');
                GO_ITEM('BLOCK.NEW_PASSWORD');
                RAISE FORM_TRIGGER_FAILURE;
        ELSIF :BLOCK.RETYPE_NEW_PASSWORD IS NULL THEN
                BELL;
                MESSAGE('PLEASE ENTER NEW PASSWORD VERIFICATION. ');
                MESSAGE(' ');
                GO_ITEM('BLOCK.RETYPE_NEW_PASSWORD');
                RAISE FORM_TRIGGER_FAILURE;
        ELSIF :BLOCK.NEW_PASSWORD != :BLOCK.RETYPE_NEW_PASSWORD THEN
                BELL;
                MESSAGE('PLEASE RETYPE NEW PASSWORD. VERIFICATION FAILED. ');
                MESSAGE(' ');
                GO_ITEM('BLOCK.NEW_PASSWORD');
                :BLOCK.NEW_PASSWORD := NULL;
                :BLOCK.RETYPE_NEW_PASSWORD := NULL;
                RAISE FORM_TRIGGER_FAILURE;
        END IF;

        IF PW = :BLOCK.OLD_PASSWORD THEN
                FORMS_DDL('ALTER USER ' ||  UN || ' IDENTIFIED BY ' ||
                           :BLOCK.NEW_PASSWORD);
                MESSAGE('PASSWORD HAS BEEN UPDATED. ');
                MESSAGE(' ');
                LOGOUT;
                PW := :BLOCK.NEW_PASSWORD;
                IF CN IS NOT NULL THEN
                   LOGON(UN,PW || '@' || CN);
                ELSE
                   LOGON(UN,PW);
                END IF;
                :BLOCK.OLD_PASSWORD := NULL;
                :BLOCK.NEW_PASSWORD := NULL;
                SYNCHRONIZE;
        ELSE
                MESSAGE('SORRY! INVALID OLD PASSWORD. ');
                MESSAGE(' ');
        END IF;
   END;

The built-in GET_APPLICATION_PROPERTY gets the information regarding
the connection including the connect string; this argument was introduced
in Forms 4.0.13.  Next, you implement a security feature to ensure
the user changing the password is the real user, not somebody else
who walked by and decided to change the password.  Hence, the user is forced to
enter the old password for security reasons, a new password, then retype the
new password.

After entering the old and new password, the user can click on the button
to start the process.  FORMS_DDL goes to the database and executes the ALTER
command with the new password.  However, this change is not noticed in the
form.  In other words, GET_APPLICATION_PROPERTY still gets the old password
as the current password.  The only way to update the application is by
logging out and logging back in.  If the user plans to change the password at
least twice in the same session, the logout and logon statements then need
to be implemented in the trigger.  Next time the user tries to change the
password within the same session, GET_APPLICATION_PROPERTY retrieves
the new password.

In Forms 4.0.12, the connect string is appended to the username.  Hence, the
GET_APPLICATION_PROPERTY built-in returns username@connect_string.
The following example shows how to implement the same functionality in
Forms 4.0.12.

   WHEN-BUTTON-PRESSED-TRIGGER
   ===========================

    DECLARE
        UN VARCHAR2(80);
        PW VARCHAR2(80);
        CN VARCHAR2(80);

    BEGIN
        GET_CONNECT_INFO(UN,PW,CN);

        IF :BLOCK.OLD_PASSWORD IS NULL THEN
                BELL;
                MESSAGE ('PLEASE ENTER OLD PASSWORD ');
                MESSAGE(' ');
                GO_ITEM('BLOCK.OLD_PASSWORD.');
                RAISE_FORM_TRIGGER_FAILURE;
        END IF;

        IF :BLOCK.NEW_PASSWORD IS NULL THEN
                BELL;
                MESSAGE('PLEASE ENTER NEW PASSWORD. ');
                MESSAGE(' ');
                GO_ITEM('BLOCK.NEW_PASSWORD');
                RAISE FORM_TRIGGER_FAILURE;
        ELSIF :BLOCK.RETYPE_NEW_PASSWORD IS NULL THEN
                BELL;
                MESSAGE('PLEASE ENTER NEW PASSWORD VERIFICATION. ');
                MESSAGE(' ');
                GO_ITEM('BLOCK.RETYPE_NEW_PASSWORD');
                RAISE FORM_TRIGGER_FAILURE;
        ELSIF :BLOCK.NEW_PASSWORD != :BLOCK.RETYPE_NEW_PASSWORD THEN
                BELL;
                MESSAGE('PLEASE RETYPE NEW PASSWORD. VERIFICATION FAILED. ');
                MESSAGE(' ');
                GO_ITEM('BLOCK.NEW_PASSWORD');
                :BLOCK.NEW_PASSWORD := NULL;
                :BLOCK.RETYPE_NEW_PASSWORD := NULL;
                RAISE FORM_TRIGGER_FAILURE;
        END IF;

        IF PW = :BLOCK.OLD_PASSWORD THEN

                 FORMS_DDL('ALTER USER ' ||  UN || ' IDENTIFIED BY ' ||
                           :BLOCK.NEW_PASSWORD);

                MESSAGE('PASSWORD HAS BEEN UPDATED. ');
                MESSAGE(' ');
                LOGOUT;

                IF CN IS NOT NULL THEN
                        LOGON(UN, :BLOCK.NEW_PASSWORD || '@' || CN);
                ELSE
                        LOGON(UN,PW);
                END IF;

                :BLOCK.OLD_PASSWORD := NULL;
                :BLOCK.NEW_PASSWORD := NULL;
                :BLOCK.RETYPE_NEW_PASSWORD := NULL;
                SYNCHRONIZE;
         ELSE
                MESSAGE('SORRY! INVALID OLD PASSWORD. ');
                MESSAGE(' ');
        END IF;
   END;

5.  Create the GET_CONNECT_INFO procedure.

    PROCEDURE GET_CONNECT_INFO (the_username IN OUT VARCHAR2,
                                the_password IN OUT VARCHAR2,
                                the_connect  IN OUT VARCHAR2)  IS
    BEGIN
      the_username := GET_APPLICATION_PROPERTY(USERNAME);
      the_password := GET_APPLICATION_PROPERTY(PASSWORD);
      the_connect  := GET_APPLICATION_PROPERTY(CONNECT_STRING);
    END;

Refer to GET_APPLICATION_PROPERTY in chapter 3, "Built-in Subprograms",
of the Oracle Forms 4.X Reference Manual, Volume 1.

6. Create a trigger KEY-DOWN at the block level.

   KEY-DOWN
   ========

   NEXT_ITEM;

7. Create a trigger KEY-NXTREC at the block level.

   KEY-NXTREC
   ===========

   NULL;

These two triggers prevent the user from going to the next record, which
clears the current record on the screen if the user presses the Down or
Next_Record key.