Database user session gets created after session kill - sql

After killing session by using ALTER SYSTEM KILL SESSION, I tried to drop the user, but it says the user is connected.
So when I again killed the session and tried to drop the user, I observed that each time I kill a session, immediately another session is getting created.
Example :
I run the query "Drop user cascade" : it says user connected cannot drop
I run the query:
SELECT 'ALTER SYSTEM KILL SESSION '''||s.sid||','|| s.serial#||''';'
FROM v$session s, v$process p
WHERE lower(s.username) = 'username'
AND p.addr(+) = s.paddr and status='INACTIVE';
I get a query to kill sessions, now I kill all the sessions and run the drop user command again, it says user connected.
Checking for sessions again on the user shows a single inactive session which is getting created each time.

Dropping a user for an application that quickly reconnects may require a few steps:
Prevent the user from reconnecting with alter user username account lock
Kill the user's sessions with alter system kill session ...
Wait for any long-running transactions to rollback. Monitor the rollback progress by repeatedly running select used_urec, gv$transaction.* from gv$transaction
Drop the user with drop user username

Related

How to kill own Oracle SQL sessions without DBA privileges?

Is there a way for a user to terminate one's own session/connections, given an Oracle SID, without DBA rights?
Specifically, I can run this in my DB without admin rights:
SELECT SID, "SERIAL#", STATUS, USERNAME
FROM V$SESSION
WHERE
(USERNAME = 'LastF')
AND
(STATUS = 'INACTIVE');
But when I go to kill my orphaned session (from another session to which I still have access),
ALTER SYSTEM KILL SESSION "12, 123"
I get the following:
JDBC ERROR: ORA-01031: insufficient privileges
Note: I am connecting with JDBC through R/Rstudio using the RJDBC package.
Motivation:
It doesn't appear too difficult to kill sessions in Oracle SQL:
https://docs.oracle.com/cd/B28359_01/server.111/b28310/manproc008.htm#ADMIN11192
How can I kill all sessions connecting to my oracle database?
However, for non-DBA users who have orphaned connections (i.e. internet outage, 3rd party client that manages connections errors out, etc), it can be really frustrating to get:
ORA-02391 exceeded simultaneous SESSIONS_PER_USER limit
and have to wait for timeout.
To successfully run an ALTER SYSTEM command, you don't need to be the DBA, but you do need the ALTER SYSTEM privilege to be granted to you (or to the "user" owning the application through which you connect to the database - which may be different from "you" as the "user" of RStudio).
You have a few options:
ask the DBA to kill the session
ask to be granted the ALTER SYSTEM privilege (which is a very poor practice)
have a "supervisor" (however defined - responsible specifically for these situations) be granted the ALTER SYSTEM privilege, who will be in charge of killing such sessions
(perhaps the best option) create a packaged
procedure whose only task is to kill orphaned sessions. Grant ALTER SYSTEM to the package owner, and grant execute privilege on that
package to individual users (as needed). The procedure should be
written to only kill specific kinds of sessions.
You can use the below to cancel whatever is running in the session
DECLARE
l_status v$session.status%TYPE;
BEGIN
dbms_system.set_ev( &sid, &serial, 10237, 1, '');
LOOP
SELECT status INTO l_status FROM v$session
WHERE sid = &sid and serial# = &serial;
EXIT WHEN l_status='INACTIVE';
END LOOP;
dbms_system.set_ev( &sid, &serial, 10237, 0, '');
END;
you will have to create a direct select grant on sys.v_$session
grant select on v_$session to
Where is the schema that owns the above procedure. This has to be a direct grant and not through a role.
Check the link for more details and given by Donald Burleson
we can kill the oracle session with pid ,
if you are unable to identify the operating system process identifier (spid) from the query , you can issue the following query to help identify the correct session:
SELECT s.sid, s.serial#, p.spid
FROM v$process p, v$session s
WHERE p.addr = s.paddr
AND s.username = '<username>';
At the operating system prompt, issue the kill command and supply the operating system process identifier (spid):
kill <spid>

Trigger Oracle connect database

How I can make a trigger that a user connect to database check if user System is connected in this moment. Is correct? Then error message and user no connect to database.
Thanks guys.
First, I want to point out that it sounds like you're trying to recreate the functionality of the command ALTER SYSTEM ENABLE RESTRICTED SESSION. You might consider just using that instead.
On the topic of your question, there's an easy answer, but it isn't very good.
CREATE OR REPLACE TRIGGER logon_system_maintenance
AFTER LOGON on DATABASE
IS
system_is_connected varchar2(1) := 'N';
BEGIN
select 'Y' into system_is_connected
from v$session
where username = 'SYSTEM' and status = 'ACTIVE';
-- this will not prevent users with ADMINISTER DATABASE TRIGGER privilege from connecting
RAISE_APPLICATION_ERROR (-20001, 'SYSTEM user is performing maintenance, please try again later');
EXCEPTION
WHEN NO_DATA_FOUND THEN
null; -- system not connected, OK
WHEN OTHERS THEN
null; -- probably the user doesn't have permission to view V$SESSION!
-- should they be able to connect, or not?
END;
/
The problem here is that in order to check if SYSTEM is connected, the user connecting has to be able to view the V$SESSION view, which means they need the SELECT_CATALOG_ROLE role. Probably most of your users don't have this role, which means they don't have permission to even check if SYSTEM is connected or not!
In my experience, what most applications do is create a table to hold various system parameters (e.g. MY_PARAM_TABLE), and add a parameter which controls whether users can log in or not (e.g. SYSTEM_MAINTENANCE = 'N'). Then when you log on as SYSTEM, you set that flag to Y, and the trigger checks that table (which all users should be able to access) and denies access until you set it back to N.
Also keep in mind that you can't prevent DBA users from logging in this way.

Cannot drop disconnected oracle user

I am trying to drop a user from an Oracle DB (version 12c), but can not get it to work. The error I am getting is:
ORA-01940: cannot drop a user that is currently connected
Naturally I looked around, and found out how to forcibly disconnect and kill a session. So I used the query:
select s.sid, s.serial#, status, s.username
from v$session s
where username = 'user_i_want_to_drop';
and then killed the only active session by using
alter system kill session '<sid>,<serial#>' IMMEDIATE;
naturally using the values from the query.
When I run the query again, it comes up empty, as expected. However, I still cannot drop the user and get the same error message.
I have noticed that when I query on gv$session, two sessions for that user show up. However, I cannot kill those using the alter system kill session statement I used above.
What am I missing here?
The other session(s) are connected to another instance of your cluster.
Add inst_id to your gv$session query, like this:
select sid,serial#,inst_id
from gv$session
where username = 'user_i_want_to_drop';
Then, include the inst_id in the alter system kill session command, like this:
alter system kill session '<sid>,<serial#>,#<inst_id>' immediate;
E.g.,
alter system kill session '15,1891,#1' immediate;

Prevent ORA-28000

I am using Oracle SQL Developer and I run into the ORA-28000 error and my account got blocked, but I resolved it from SQL plus by using the following commands:
SQL> alter user user1 account unlock;
SQL> grant connect, resource to user1;
The thing is that I want to prevent this from happening again. Where can I see the threshold of the failed login attempts that exists so that I would either raise it or delete it completely?
In the sql developer, menu in the Users option, you can edit the user and edit the amount of attempts, if the password expires, etc. However I can only log in with the system user, sys could not connect.
FAILED_LOGIN_ATTEMPTS and similar are properties of the profile associated with your user. You can check the settings with this query:
select u.profile
, p.resource_name
, p.limit
from dba_users u
join dba_profiles p
on u.profile = p.profile
where p.resource_type = 'PASSWORD';
These limits are set for the profile: you can change them but the new limits will cascade to all users with this profile:
alter profile whatever limit FAILED_LOGIN_ATTEMPTS 12;
Alternatively you can modify the user so it has a more forgiving profile:
alter user joesoap profile default;

SQL Server User Mapping Error 15023

I try to map my other DB to a user by going to Security > Logins > right click someuser > Properties > User Mapping > Select DB > set as db_owner and then ok, but I keep on getting an error saying
User, group, or role 'someuser' already exists in the current database. (Microsoft SQL Server, Error: 15023)
What is causing the error, and how do I map that user to the database?
To fix the user and login mapping you need to open a query window in the SQL Server Management Studio. Enter the following two lines and replace myDB with the database name and myUser with the correct user name:
USE myDB
EXEC sp_change_users_login 'Auto_Fix', 'myUser'
If run successfully you should get an output like this one:
The row for user '****' will be fixed by updating its login link to a login already in existence.
The number of orphaned users fixed by updating users was 1.
The number of orphaned users fixed by adding new logins and then updating users was 0.**
Your user should now be mapped correctly.
Edit:
New way to Resolve/Fix an Orphaned User:
In the master database, use the CREATE LOGIN statement with the SID option to recreate a missing login, providing the SID of the database user.
CREATE LOGIN <login_name>
WITH PASSWORD = '<use_a_strong_password_here>',
SID = <SID>;
To map an orphaned user to a login which already exists in master, execute the ALTER USER statement in the user database, specifying the login name.
ALTER USER <user_name> WITH Login = <login_name>;
When you recreate a missing login, the user can access the database using the password provided. Then the user can alter the password of the login account by using the ALTER LOGIN statement.
ALTER LOGIN <login_name> WITH PASSWORD = '<enterStrongPasswordHere>';
if it is just one or two users, then easiest way is to drop the database user from the restored database, remap the database user to the server login using SSMS. If the server login does not exist then just create it, map the user.
Option 2: If you are migrating a large number of users, use sp_help_revlogin. sp_help_revlogin is a Microsoft supplied stored procedure that will help migrate logins from one server to another, including passwords and SIDs. Here is a good article about it SP_HELP_REVLOGIN : http://www.databasejournal.com/features/mssql/article.php/2228611/Migrating-Logins-from-One-SQL-Server-to-Another.htm
Code patches to help use it :
run following T-SQL Query in Query Analyzer. This will return all the existing users in database in result pan.
USE YourDB
GO
EXEC sp_change_users_login 'Report'
GO
Run following T-SQL Query in Query Analyzer to associate login with the username. ‘Auto_Fix’ attribute will create the user in SQL Server instance if it does not exist. In following example ‘ColdFusion’ is UserName, ‘cf’ is Password. Auto-Fix links a user entry in the sysusers table in the current database to a login of the same name in sysxlogins.
USE YourDB
GO
EXEC sp_change_users_login 'Auto_Fix', 'ColdFusion', NULL, 'cf'
GO
Run following T-SQL Query in Query Analyzer to associate login with the username. ‘Update_One’ links the specified user in the current database to login. login must already exist. user and login must be specified. password must be NULL or not specified
USE YourDB
GO
EXEC sp_change_users_login 'update_one', 'ColdFusion', 'ColdFusion'
GO
2) If login account has permission to drop other users, run following T-SQL in Query Analyzer. This will drop the user.
USE YourDB
GO
EXEC sp_dropuser 'ColdFusion'
GO
Create the same user again in the database without any error.
If you assign permissions to a database user without mapping it to the database first, it throws the error you mentioned.
You should be able to delete the user, map it to the database and then assign the user to the db_owner role.
First drop your user, then execute the script below:
USE [YOURDB]
GO
CREATE USER [USERNAME] FOR LOGIN [USERNAME]
GO
USE [YOURDB]
GO
ALTER USER [USERNAME] WITH DEFAULT_SCHEMA=[dbo]
GO
I had the problem when I was trying to copy a production database to a local test database. In SSMS, I made sure to disconnect from the production server before executing scripts on the local. However, even though I thought I had disconnected, someone pointed out that the title of the production database was still there, and I got errors that objects were already there. The solution was to totally exit from SSMS and start it again, only connecting to the local test database that time.
you can solve problem by expand database ->Security -> Users
and delete the user 'someuser' ,after that go to user mapping and assign.
this problem happen some times because the database user 'someuser' was deleted from 'Logins' in Security section in SSMS and the database still own this user
Create failed for User (Microsoft.SqlServer.Smo)
SQL Server Error User, group, or role already exists in the current database. (Microsoft SQL Server, Error: 15023)
To fix above error delete user under each database individually