OK, I'll share with everyone, though this is going to get LONG. First create a user inside your database that you know the password to & = no one else does. Inside this do the following: create table password(username varchar2(30) constraint passwd_pk primary key, ps_password varchar2(30) not null) storage(initial 32K next 32K pctincrease 0); create table psaccess(username varchar2(20), priv_user varchar2(40) not null, server_name varchar2(30) not null) storage(initial 32K next 32K pctincrease 0); alter table psaccess add constraint psacc_fk foreign key (username) references password(username) on delete cascade; create table psaccess_audit(priv_user varchar2(40), username varchar2(30), server_name varchar2(30), date_of_access date default sysdate, status varchar2(10)) storage(initial 512K next 512K pctincrease 0); Now populate password with the usernames (upper case please) and = passwords needed. The passwords need to be encrypted. The encrypt = package below does that. It's not RSA secure, more like PGP. Fill in = psaccess with the username you want user, the Unix login name of the = user (case sensitive) and the server's name (case sensitive). create or replace package encrypt as function code(inp_data varchar2, key varchar2 default = 'MY_ENCRPTY_KEY') return varchar2; pragma restrict_references(code, RNDS, WNDS, WNPS); end; / create or replace package body encrypt is function convbin(c1 varchar2) return varchar2 is loop1 number; value number; divis number; r1 varchar2(30); begin r1 :=3D ''; divis :=3D 128; value :=3D ascii(c1); for loop1 in 0..7 loop if(trunc(value/divis) =3D 1) then r1 :=3D r1||'1'; else r1 :=3D r1||'0'; end if; value :=3D mod(value, divis); divis :=3D divis/2; end loop; return r1; end; =20 function code(inp_data varchar2, key varchar2 default = 'MY_ENCRYPT_KEY') return varchar2 is loop1 number; loop11 number; r1 varchar2(8); r2 varchar2(8); key1 varchar2(4000); r3 number; result varchar2(40); divis number; begin key1 :=3D key; while (length(inp_data) > length(key1)) loop key1 :=3D key1||key1; end loop; result :=3D ''; for loop1 in 1..length(inp_data) loop r1 :=3D convbin(substr(inp_data,loop1,1)); r2 :=3D convbin(substr(key1,loop1,1)); divis :=3D 128; r3 :=3D 0; for loop11 in 1..8 loop = if(to_number(substr(r1,loop11,1))+to_number(substr(r2,loop11,1)) =3D 1) = then r3 :=3D r3+divis; end if; divis :=3D divis/2; end loop; result :=3D result||chr(r3); end loop; return result; end; end; / grant execute on encrypt to public; create public synonym encrypt for system.encrypt; Recommend changing "MY_ENCRYPT_KEY" to a more acceptable key. Also = recommend it be in the SYSTEM schema & that you wrap it with Oracle's = WRAP utility. Now as the Oracle user on Unix, compile the following Pro*C program. #include <stdio.h> #include <stdlib.h> EXEC SQL BEGIN DECLARE SECTION; VARCHAR usr[20]; VARCHAR pwd[20]; VARCHAR db[20]; VARCHAR upass[20]; VARCHAR sname[20]; VARCHAR state[11]; char *evkr =3D NULL; VARCHAR nme[30]; EXEC SQL END DECLARE SECTION; EXEC SQL INCLUDE SQLCA; int main(int argc, char *argv[]) { char rval[20]; FILE *p =3D NULL; int pv =3D 0; rval[0] =3D '\0'; strcpy(usr.arr, "YOUR_SCHEMA"); strcpy(pwd.arr, "YOUR_PASSWORD"); usr.len =3D strlen(usr.arr); pwd.len =3D strlen(pwd.arr); p =3D popen("/usr/bin/hostname", "r"); if(p) { fgets(rval, sizeof(rval), p); pv =3D pclose(p); } strcpy(sname.arr, rval); sname.len =3D strlen(sname.arr)-1; if(argc =3D=3D 3) { strcpy(db.arr, argv[2]); db.len =3D strlen(db.arr); EXEC SQL CONNECT :usr IDENTIFIED BY :pwd USING :db; } else { EXEC SQL CONNECT :usr IDENTIFIED BY :pwd; } if(sqlca.sqlcode !=3D 0) exit(1); evkr =3D getenv("LOGNAME"); if(argc >=3D 2) { strcpy(nme.arr, argv[1]); nme.len =3D strlen(nme.arr); EXEC SQL SELECT ENCRYPT.CODE(PS_PASSWORD) INTO :upass FROM PASSWORD A, PSACCESS B WHERE A.USERNAME =3D B.USERNAME AND PRIV_USER =3D :evkr AND B.USERNAME =3D UPPER(:nme) AND B.SERVER_NAME =3D :sname; } else { EXEC SQL SELECT ENCRYPT.CODE(PS_PASSWORD), A.USERNAME INTO :upass, :nme FROM PASSWORD A, PSACCESS B WHERE A.USERNAME =3D B.USERNAME AND PRIV_USER =3D :evkr AND B.SERVER_NAME =3D :sname; } if(sqlca.sqlcode !=3D 0) { upass.arr[0] =3D '\0'; strncpy(state.arr, sqlca.sqlerrm.sqlerrmc, 10); } else { upass.arr[upass.len] =3D '\0'; strcpy(state.arr, "PASS"); } state.len =3D strlen(state.arr); EXEC SQL INSERT INTO PSACCESS_AUDIT VALUES(:evkr, :nme, :sname, SYSDATE, :state); if(sqlca.sqlcode !=3D 0) { EXEC SQL ROLLBACK WORK RELEASE; } else { EXEC SQL COMMIT WORK RELEASE; } printf("%s", upass.arr); exit(0); } NOTE: Put the username & Password in the right places above. Compile = with: proc iname=3Dpspass.pc oname=3Dpspass.c make -f $ORACLE_HOME/rdbms/demo/demo_rdbms.mk EXE=3Dpspass = OBJS=3Dpspass.o To use: sqlplus scott/`pspass scott MYDB`@MYDB If you want I've a NT/Windoze 2k equavilent as well. Not as pretty, but = it works. The nice part here is that it audits itself incase your = paranoid. =20 Dick Goulet Senior Oracle DBA Oracle Certified 8i DBA ---------------------------------------------------------------- Please see the official ORACLE-L FAQ: http://www.orafaq.com ---------------------------------------------------------------- To unsubscribe send email to: oracle-l-request@xxxxxxxxxxxxx put 'unsubscribe' in the subject line. -- Archives are at //www.freelists.org/archives/oracle-l/ FAQ is at //www.freelists.org/help/fom-serve/cache/1.html -----------------------------------------------------------------