Oracle: idle_time appears to be ignored - oracle

In my understanding, creating a profile with the idle_time set to a certain value (in minutes) and creating a user with this profile should force the SNIPED status for that user's session in case he is idle for longer than idle_time. When the user tries to execute a query after this has happened, he receives a message that he must connect again.
First question: Is that right? If so, read on:
I'm running a test script as follows in sqlplus (without the placeholders obviously):
connect system/<password>#<tns>
CREATE PROFILE test_profile LIMIT idle_time 1;
CREATE USER test_user PROFILE test_profile IDENTIFIED BY test_user;
GRANT CREATE SESSION TO test_user;
GRANT ALTER SESSION TO test_user;
GRANT SELECT ON <schema>.<table> TO test_user;
disconnect;
connect test_user/test_user#<tns>
SELECT * FROM <schema>.<table>;
Everything works up to this point; the sqlplus window is still open. Now I open an additional sqplus window and connect using the system account, running the following query after doing other stuff for a while:
SELECT username, status, seconds_in_wait FROM v$session WHERE username = 'test_user';
I get something like:
USERNAME STATUS SECONDS_IN_WAIT
--------- -------- ---------------
TEST_USER INACTIVE 1166
Why has the status not been set to SNIPED?
Obviously, If I run another query from the test_user's sqlplus window, I do not get a message asking me to reconnect.

You need to set the database's RESOURCE_LIMIT parameter to TRUE in order for resource limits in profiles to take effect. Assuming you use a spfile (otherwise omit the scope = BOTH part)
ALTER SYSTEM SET resource_limit = TRUE scope = BOTH
Once you do that, PMON should start sniping the sessions that have exceeded your IDLE_TIME when it wakes up every few minutes.

Related

Oracle SERIAL# changing for the same SID

I'm using Oracle19c with a thin client and I'd like to set traces on the 5 application connections with
EXEC DBMS_SYSTEM.set_sql_trace_in_session(sid, serial#, true ) so I created a stored procedure.
When I select the SID and SERIAL# with:
select sid, serial#, osuser, machine, program, module, username
from v$session WHERE username IS NOT NULL ORDER BY username ASC;
I noticed that the SERIAL# keeps changing every minute or so, but I don't have any connection timeout set for the user: it's using the DEFAULT profile and LIMIT='UNLIMITED'.
Is there a way to "extend the life" of those connections?
A new serial# is a new session. This probably means the application doing the connecting is diconnecting/reconnecting, possibly by design at regular intervals, or possibly by error and its dropping the connection and recovering by commencing a new one.
But you'll need to look inside the app to see that, not the database.
If you want to trace such an app, you could create a LOGON trigger to turn on trace as soon as they connect, rather than trying to catch it with a query to v$session, eg
create or replace
trigger TRACE_ALL_LOGINS
after logon on MY_DB_ACCOUNT.schema
begin
execute immediate 'alter session set tracefile_identifier = BLAH';
execute immediate 'alter session set events = ''10046 trace name context forever, level 12''';
exception
when others then null;
end;
/
I keep the when-others-then-null in this special case to ensure that if the trigger fails for some reason, we don't block the ability to connect at all.

Users are created with the flag "ORACLE_MAINTAINED" = "Y"

I am trying to create a new user in Oracle with the following script, executed as the 'SYSTEM' user:
alter session set "_ORACLE_SCRIPT"=true;
create user my_user identified by my_password;
I am aware that this user does not have any grants yet, but I am wondering why Oracle creates this user as a system user. If I run the following query:
select USERNAME, ORACLE_MAINTAINED from SYS.ALL_USERS where username = 'my_user'
then I am receiving the result
USERNAME ORACLE_MAINTAINED
------------------------- -
MY_USER Y
I am using flyway to handle the schema which belongs to the user, and it refuses to clean up my schema because it assumes that the schema is system maintained, due to the 'ORACLE_MAINTAINED' flag. What am I doing wrong?

ora-00020 maximum number of processes

Recently, I have been facing this error
ora-00020 maximum number of processes
I have read articles that says that I have to increase the number of processes, sessions, and the transactions.
I tried. and Simply I have done the followings:
I logged in as SYSDBA to the database.
I tried to use the following command:
alter system set processes = 500 scope = psfile
to increase the sessions and the transactions I need to follow the equations below :
sessions = (1.1*processes) + 5
transactions = (1.1*sessions)
well, I am not sure if it's correct or not.
so, I tried to increase the processes first by the command above.
I got another error
[code] ora-02095: specified initialization parameter cannot be modified[/code]
After reading about ora-02095. I found that I have to check the scope if it's spfile or pfile.
SELECT DECODE(value, NULL, 'PFILE', 'SPFILE') "Init File Type"
FROM sys.v_$parameter WHERE name = 'spfile';
no rows selected
can you please help me
The Solution :
Go to database files
go to ADMIN\database\pfile\init.ora
open it
change
processes = 59
to
processes = 200
then shutdown and start the database.
Problem Solved. Thanks for all.
Open cmd as Administrator
C:\Users\Usuario> sqlplus "/as sysdba"
SQL> alter system set processes=500 scope=spfile;
SQL> shutdownimmediate
SQL> startup
SQL> show parameter processes

Oracle kill inactive sessions stored procedure

I would like to write kill_inactive sessions stored procedure for Oracle.
something like
create or replace procedure kill_inactive_sessions as
begin
for rec in (select sid, serial# from sys.v_$session where status = 'INACTIVE')
loop
execute immediate 'alter system kill session '''|| rec.sid || ',' || rec.serial# || ''' IMMEDIATE';
end loop;
end kill_inactive_sessions;
Previous doesn't work (table or view does not exists).
But next select is working perfectly for the same user:
select sid, serial# from sys.v_$session where status = 'INACTIVE';
What I'm missing?
The ORA-00942: table or view does not exist error almost certainly indicates that your access to the v$session view is via a role rather than a direct grant.
If you want to write a definer's rights stored procedure, the owner of the procedure must have the necessary privileges granted directly to the user, not via a role (and remember that DBA is just another role). Most likely, if you disabled roles in your session, the SELECT statement outside of the procedure would not work. In SQL*Plus, for example
SQL> set role none;
SQL> select sid, serial# from sys.v_$session where status = 'INACTIVE';
will likely throw the same ORA-00942 error. Assuming it does, you need to grant the user that owns the stored procedure privileges directly. For example
GRANT SELECT ANY DICTIONARY
TO user_that_owns_the_procedure;
The same thing will also apply to the ALTER SYSTEM command that you are building and running. The owner of the stored procedure will need to have privileges to run that command via a direct grant not via a role.
All that said, a procedure that kills all inactive sessions is highly problematic. The vast majority of sessions are going to be inactive the vast majority of the time. That doesn't mean that they should be killed. Even if you're cleaning up after an application server crash, you really ought to be applying some additional predicates (for example, looking for sessions from a particular machine that are logged in as a particular user that were established before the application server crashed). Long-term, though, I'd suggest enabling dead connection detection so that the database can automatically take care of closing sessions when the client process dies unexpectedly.

How do I turn off Oracle password expiration?

I'm using Oracle for development. The password for a bootstrap account that I always use to rebuild my database has expired.
How do I turn off password expiration for this user (and all other users) permanently?
I'm using Oracle 11g, which has passwords expire by default.
To alter the password expiry policy for a certain user profile in Oracle first check which profile the user is using:
select profile from DBA_USERS where username = '<username>';
Then you can change the limit to never expire using:
alter profile <profile_name> limit password_life_time UNLIMITED;
If you want to previously check the limit you may use:
select resource_name,limit from dba_profiles where profile='<profile_name>';
For development you can disable password policy if no other profile was set (i.e. disable password expiration in default one):
ALTER PROFILE "DEFAULT" LIMIT PASSWORD_VERIFY_FUNCTION NULL;
Then, reset password and unlock user account. It should never expire again:
alter user user_name identified by new_password account unlock;
As the other answers state, changing the user's profile (e.g. the 'DEFAULT' profile) appropriately will lead to passwords, that once set, will never expire.
However, as one commenter points out, passwords set under the profile's old values may already be expired, and (if after the profile's specified grace period) the account locked.
The solution for expired passwords with locked accounts (as provided in an answering comment) is to use one version of the ALTER USER command:
ALTER USER xyz_user ACCOUNT UNLOCK;
However the unlock command only works for accounts where the account is actually locked, but not for those accounts that are in the grace period, i.e. where the password is expired but the account is not yet locked. For these accounts the password must be reset with another version of the ALTER USER command:
ALTER USER xyz_user IDENTIFIED BY new_password;
Below is a little SQL*Plus script that a privileged user (e.g. user 'SYS') can use to reset a user's password to the current existing hashed value stored in the database.
EDIT: Older versions of Oracle store the password or password-hash in the pword column, newer versions of Oracle store the password-hash in the spare4 column. Script below changed to collect the pword and spare4 columns, but to use the spare4 column to reset the user's account; modify as needed.
REM Tell SQL*Plus to show before and after versions of variable substitutions.
SET VERIFY ON
SHOW VERIFY
REM Tell SQL*Plus to use the ampersand '&' to indicate variables in substitution/expansion.
SET DEFINE '&'
SHOW DEFINE
REM Specify in a SQL*Plus variable the account to 'reset'.
REM Note that user names are case sensitive in recent versions of Oracle.
REM DEFINE USER_NAME = 'xyz_user'
REM Show the status of the account before reset.
SELECT
ACCOUNT_STATUS,
TO_CHAR(LOCK_DATE, 'YYYY-MM-DD HH24:MI:SS') AS LOCK_DATE,
TO_CHAR(EXPIRY_DATE, 'YYYY-MM-DD HH24:MI:SS') AS EXPIRY_DATE
FROM
DBA_USERS
WHERE
USERNAME = '&USER_NAME';
REM Create SQL*Plus variable to hold the existing values of the password and spare4 columns.
DEFINE OLD_SPARE4 = ""
DEFINE OLD_PASSWORD = ""
REM Tell SQL*Plus where to store the values to be selected with SQL.
REM Note that the password hash value is stored in spare4 column in recent versions of Oracle,
REM and in the password column in older versions of Oracle.
COLUMN SPARE4HASH NEW_VALUE OLD_SPARE4
COLUMN PWORDHASH NEW_VALUE OLD_PASSWORD
REM Select the old spare4 and password columns as delimited strings
SELECT
'''' || SPARE4 || '''' AS SPARE4HASH,
'''' || PASSWORD || '''' AS PWORDHASH
FROM
SYS.USER$
WHERE
NAME = '&USER_NAME';
REM Show the contents of the SQL*Plus variables
DEFINE OLD_SPARE4
DEFINE OLD_PASSWORD
REM Reset the password - Older versions of Oracle (e.g. Oracle 10g and older)
REM ALTER USER &USER_NAME IDENTIFIED BY VALUES &OLD_PASSWORD;
REM Reset the password - Newer versions of Oracle (e.g. Oracle 11g and newer)
ALTER USER &USER_NAME IDENTIFIED BY VALUES &OLD_SPARE4;
REM Show the status of the account after reset
SELECT
ACCOUNT_STATUS,
TO_CHAR(LOCK_DATE, 'YYYY-MM-DD HH24:MI:SS') AS LOCK_DATE,
TO_CHAR(EXPIRY_DATE, 'YYYY-MM-DD HH24:MI:SS') AS EXPIRY_DATE
FROM
DBA_USERS
WHERE
USERNAME = '&USER_NAME';
I believe that the password expiration behavior, by default, is to never expire. However, you could set up a profile for your dev user set and set the PASSWORD_LIFE_TIME. See the orafaq for more details. You can see here for an example of one person's perspective and usage.
I will suggest its not a good idea to turn off the password expiration as it can lead to possible threats to confidentiality, integrity and availability of data.
However if you want so.
If you have proper access use following SQL
SELECT username, account_status FROM dba_users;
This should give you result like this.
USERNAME ACCOUNT_STATUS
------------------------------ -----------------
SYSTEM OPEN
SYS OPEN
SDMADM OPEN
MARKETPLACE OPEN
SCHEMAOWNER OPEN
ANONYMOUS OPEN
SCHEMAOWNER2 OPEN
SDMADM2 OPEN
SCHEMAOWNER1 OPEN
SDMADM1 OPEN
HR EXPIRED(GRACE)
USERNAME ACCOUNT_STATUS
------------------------------ -----------------
APEX_PUBLIC_USER LOCKED
APEX_040000 LOCKED
FLOWS_FILES LOCKED
XS$NULL EXPIRED & LOCKED
OUTLN EXPIRED & LOCKED
XDB EXPIRED & LOCKED
CTXSYS EXPIRED & LOCKED
MDSYS EXPIRED & LOCKED
Now you can use Pedro CarriƧo answer https://stackoverflow.com/a/6777079/2432468
For those who are using Oracle 12.1.0 for development purposes:
I found that the above methods would have no effect on the db user: "system", because the account_status would remain in the expired-grace period.
The easiest solution was for me to use SQL Developer:
within SQL Developer, I had to go to: View / DBA / Security and then Users / System and then on the right side: Actions / Expire pw and then: Actions / Edit and I could untick the option for expired.
This cleared the account_status, it shows OPEN again, and the SQL Developer is no longer showing the ORA-28002 message.

Resources