How do I turn off Oracle password expiration? - oracle

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.

Related

ora-01017 invalid username/password logon denied can't logon with the new connection

Hey please am using oracle 11g XE and I have created a new user under the username "amine" and set the password to "amine" in SQL developer,
I have also granted all permissions and system privileges but when I try to create a new connection using the "amine" user it gives an ora-01017 even if the username and the password are correct
Steps that I tried :
-- setting the case sensitivity to FALSE
-- make sure that the user is created and the status is open (using sqlplus)
-- tried the command: alter user amine identified by "amine"; result ---> ORA-01918: user 'AMINE' does not exist
I have created a new user under the username "amine"
It sounds like you have used the query:
CREATE USER "amine" IDENTIFIED BY "amine";
This will create a case-sensitive username and a case-sensitive password as you have surrounded the identifiers with double quotes.
If you try in SQL/Plus (or via equivalents in other UI such as SQL Developer's connection dialog) to use any one of these:
CONN amine/amine
CONN "amine"/amine
CONN amine/"amine"
Then it will fail as the unquoted values will be implicitly converted to upper-case as Oracle stores non-case-sensitive identifiers in upper-case.
You would always need to quote both the username and the password. I.e. in SQL/Plus
CONN "amine"/"amine"
Or using quotes in the username field in SQL Developer.
You can check if you did this by running:
SELECT username
FROM all_users
WHERE UPPER(username) = 'AMINE';
If the value comes back as lower-case (or, even, if there are now two users amine and AMINE) then you created the first one with a case-sensitive username and you will need to surround the username with double quotes whenever you want to use it.
Such as:
GRANT CREATE SESSION TO "amine";

How to know user's "expiry_date" changed?

I'm faced with a very specific task with Oracle.
I need to prove that values in column expiry_date of table dba_users were not changed in a certain period (during last weekend).
I am not very experienced with Oracle. For me, it seems like a feature called "audit" is disabled, but I'm not strongly sure.
So, I need whatever option to check whether these values have been changed. I have already tried to analyze the user_sessions table (having the intent to check for connections during the period in question), but with that, I couldn't get an exact answer.
Instead of trying to directly detect changes to dba_users.expiry_date, it would be much easier to detect when a user changes their password, which would indirectly change the expiry date:
select password_date
from sys.user_history$
join dba_users
on sys.user_history$.user# = dba_users.user_id
where username = '&USER'
order by password_date desc;
However, that table will only contain values if the user has a profile where the PASSWORD_REUSE_TIME is not set to unlimited. You can find that setting with these queries:
--Find the user's profile:
select profile from dba_users where username = '&USER';
--Find the PASSWORD_REUSE_TIME of the profile.
--If the value is 'DEFAULT', you'll have to run this query again for the profile 'DEFAULT'.
select limit
from dba_profiles
where resource_name = 'PASSWORD_REUSE_TIME'
and profile = '&PROFILE';
(Oracle's audit functionality does not capture this information. You can run audit alter user and then query DBA_AUDIT_TRAIL to detect when a user was changed, but you can't tell the difference between a password reset and an account locking.)
Unfortunately, the above solution doesn't cover all possible reasons why the expiration date could change. If an administrator manually expires a user, or changes a profile or profile settings, the expiration date could change. To capture all possible reasons for a change, you would need to create triggers on the system tables used by DBA_USERS and store the expiration value whenever it changes. Or you could create a job that periodically checks the view and looks for changes.
But before you consider those options, you might want to explain exactly why you want this information. I'm guessing this question is for a security audit, but this feels like the wrong kind of information to look for. What is your true goal here?

ORA-20002: YOU ARE NOT ALLOWED TO CHANGE THE PASSWORD FOR CRITICAL SCHEMAS

I'm trying to change the password for Oracle DB user but I'm getting below error:
ORA-28003: password verification for the specified password
ORA-20002: YOU ARE NOT ALLOWED TO CHANGE THE PASSWORD FOR CRITICAL SCHEMAS
I've tried to change the password using sys user and got same error.
DB version: 12.2.0.1.0
Client: SQLPlus
Please help
The exception is being raised by a password verification function, assigned to the user via a profile.
You can see the profile name and the function being applied by querying:
select du.profile, dp.limit
from dba_users du
join dba_profiles dp on dp.profile = du.profile
where du.username = '<YOUR_USER>'
and dp.resource_name = 'PASSWORD_VERIFY_FUNCTION';
You can then see what the function is actually doing by looking at its source, using the name identified in the previous query:
select text
from dba_source
where owner = 'SYS'
and name = '<FUNCTION_NAME>'
order by line;
From there you can see when and why it's happening, by looking for a line like:
raise_application_error(-20002, 'YOU ARE NOT ALLOWED TO CHANGE THE PASSWORD FOR CRITICAL SCHEMAS');
and seeing what logic leads to it being raised.
You'll need to decide whether that rule is (still) appropriate for that user - clearly it's there for a reason so don't remove it or change the user's profile without really understanding it, and discussing with the DBA and/or application owner etc. - basically anyone with an interest in that user account.

Oracle verify function 12c - string distance

The oracle verify function includes a setting which checks for the distance of the last passsword. ora12c_verify_function:
-- Check if the password differs from the previous password by at least
-- 3 characters
IF old_password IS NOT NULL THEN
differ := string_distance(old_password, password);
IF differ < 3 THEN
raise_application_error(-20010, 'Password should differ from the '
|| 'old password by at least 3 characters');
END IF;
END IF ;
RETURN(TRUE);
END;
Why it is possible to change the password with only one different character?
Connected to:
Oracle Database 12c Standard Edition Release 12.1.0.2.0 - 64bit Production
SQL> ALTER USER TEST PROFILE DEFAULT;
SQL> ALTER PROFILE default LIMIT PASSWORD_VERIFY_FUNCTION ora12c_verify_function;
SQL> alter user test identified by "123456789_abc!";
User altered.
SQL> alter user test identified by "123456789_abc!";
alter user test identified by "123456789_abc!"
*
ERROR at line 1:
ORA-28007: the password cannot be reused
SQL> alter user test identified by "123456789_abcd!";
User altered.
I found the soultion on Oracle Support Doc ID 816932.1. The issue is related to the fact that the ALTER USER privilege does not require the user to know the old password, so consequently it will not check this old password when this privilege is used. Without the privilige the user needs to supply the old password with the REPLACE command.
ALTER USER SCOTT IDENTIFIED BY NEWPASSWORD REPLACE TIGER;

Oracle: idle_time appears to be ignored

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.

Resources