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>
Related
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
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.
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;
In spite of unlocking several times, my account on oracle database is getting locked each time I try to connect to another user.
I type the following command while I am on root account:
sql> connect hr/hr
And then, I get the following error.
ERROR: ORA-28000: the account is locked
WARNING: You are no longer connected to ORACLE
You are attempting to connect to a locked account:this is not permitted. However, issuing a connect logs you out of your root account (whatever means in an Oracle context).
In order to connect to hr you need to unlock that account. This needs DBA privileges:
alter user hr account unlock;
You can change PASSWORD_LIFE_TIME parameter by using below command.
alter profile default limit PASSWORD_LIFE_TIME unlimited;
What is the diffrence between...
execute as user = 'testuser'
AND
execute as login = 'testuser'
I am executing a cross database procedure under these logins and it works with the exececute as login but not the execute as user. It is saying the server principal "testuser" is nt able to access the database "xxx" under the securty context.
When i SELECT SYSTEM_USER after both commands I see that it is set to 'testuser'
execute as login provides impersonation to the entire server, since logins are on a server level. Since users are defined per database, execute as user impersonation applies only to a specific database, which is why you see the error when you cross databases.
The EXECUTE AS can be added to stored procs, functions, triggers, etc.
Example to Execute As:
CREATE PROCEDURE dbo.MyProcedure
WITH EXECUTE AS OWNER
In this case you are impersonating the owner of the module being called.
You can also impersonate SELF, OR the USER creating or altering the module OR...
impersonate CALLER , which will enable to module to take on the permissions of the current user, OR...
impersonate OWNER, which will take on the permission of the owner of the procedure being called OR...
impersonate 'user_name', which will impersonate a specific user OR...
impersonate 'login_name' with will impersonate a specific login.
Setting permission on objects like stored procedures can be accomplished with
GRANT EXECUTE ON <schema>.<procedurename> to <username>;
However, you may also want to grant security rights at both the login and user level.
You will want to determine and grant ONLY the necessary rights
for the objects that require access (such as execution). Consider use of the "EXECUTE AS" capability which enables impersonation of another user
to validate permissions that are required to execute the code WITHOUT having to grant all of the necessary rights to all of the underlying objects (e.g. tables).
MOST of the time, you will only need to grant EXECUTE rights to stored procs and then rights are granted to all objects referenced within the stored proc.
In this way, you do not need to give implicit rights (example: to update data or call additional procs). Ownership chaining handles this for you.
This is especially helpful for dynamic sql or if you need to create elevated security tasks such as CREATE TABLE. EXECUTE AS is a handy tool to consider for these.
This example may help clarify all of this:
--Create a user called NoPrivUser with public access to a database (e.g. dbadb)
USE [master]
GO
CREATE LOGIN [NoPrivUser] WITH PASSWORD=N'ABC5%', DEFAULT_DATABASE=[dbadb], CHECK_EXPIRATION=ON, CHECK_POLICY=ON
GO
USE [DBAdb]
GO
CREATE USER [NoPrivUser] FOR LOGIN [NoPrivUser]
GO
NOTE: CREATOR OR OWNER OF THIS PROCEDURE WILL REQUIRE CREATE TABLE RIGHTS within the target database.
use DBAdb
go
CREATE PROCEDURE dbo.MyProcedure
WITH EXECUTE AS OWNER
AS
IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].MyTable') AND type in (N'U'))
CREATE TABLE MyTable (PKid int, column1 char(10))
INSERT INTO MyTable
VALUES (1,'ABCDEF')
GO
GRANT EXEC ON dbo.MyProcedure TO NoPrivUser;
GO
-- Now log into your database server as NoPrivUser and run the following.
use dbadb
go
EXEC dbo.MyProcedure
--(1 row(s) affected)
Now try to select from the new table while logged on as NoPrivuser.
You will get the following:
select * from MyTable
go
Msg 229, Level 14, State 5, Line 1 The SELECT permission was denied on
the object 'MyTable', database 'DBAdb', schema 'dbo'.
That is expected since you only ran the procedure under the security context of Owner while logged on as NoPrivUser.
NoPrivUser as no rights to actually read the table, Just to execute the procedure which creates and inserts the rows.
With the EXECUTE AS clause the stored procedure is run under the context of the object owner. This code successfully creates dbo.MyTable and rows are inserted successfully.
In this example, the user "NoPrivUser" has absolutey no granted rights to modify the table, or read or modify any of the data in this table.
It only takes on the rights needed to complete this specific task coded WITHIN the context of this procedure.
This method of creating stored procedures that can perform tasks that require elevated security rights without permanently assigning those rights come be very useful.
Login scope is at the server level while user scope is at the current database level
http://msdn.microsoft.com/en-us/library/ms181362.aspx