im in needed of help, im doing some exercises with a a oracle database and do not know how to do this:
I have a table called users that have information of the users that connect to the DB, what i want is a procedure where to show the information of a specific row where the connected user is compared to the user in the table.
i do not how to compared a data in a table to the connected user, more like i dont know how "work" or what limitations have the "user" parameter to be implemented this way
Sorry if my petition its a little confusing english is not my main language.
EX: i have a user in the table users, that have a serial id, username,password,name, surname1 and surname2 and i want the procedure to show me the information of this user in particular, but i do want that if for example im connected with "pedro" user to the db this procedure show me the info about the user pedro and if i change the user connected to another like Paul the information of the select change to Paul.
One option might be to use the USER function.
SQL> connect scott/tiger#orcl
Connected.
SQL> select user from dual;
USER
------------------------------
SCOTT
SQL>
Therefore you'd
select serial id,
username,
password,
name,
surname1,
surname2
from users
where username = user;
You can find the currently connected user with
select sys_context('USERENV','CURRENT_USER') from dual;
I am trying to create a view in Oracle using Toad and getting error table or view doesn't exist.
But when I run the query on its own it executes successfully. What is the possible reason ?
CREATE OR REPLACE FORCE VIEW MGR.V_INDEX_PERFORMANCE
(
INDEX_ID ,
INDEX_NAME,
MTD,
YTD
)
BEQUEATH DEFINER
AS
SELECT "INDEX_ID" ,
"INDEX_NAME",
"MTD",
"YTD" from MIS_PERMAL.MV_INDEX_PERFORMANCE
where INDEX_ID in (1045, 2005) AND FIELD_CODE = 'TR' AND CCY_CODE IN ('D', 'USD') order by INDEX_ID, price_date desc;
It's permissions, or rather the way they are granted. The MGR user has a privilege to query the underlying table which comes from a role. Oracle does not allow us to build views or procedures using privileges from a role. This is just the way the security model works.
The solution is to ask the table owner MIS_PERMAL (or a power user such as a DBA) to grant the SELECT privilege on MV_INDEX_PERFORMAMCE directly to MGR.
I have a question about Oracle and checking privileges.
Some background Info
I wrote some php scripts that will 'test' various things in our environment. One of those tasks is checking that a user has execute privileges on a procedure and that the procedure is valid/compiled.
Here is the query
select ao.object_name, utp.grantee, ao.status, utp.privilege
from all_objects ao, user_tab_privs utp
where utp.owner = ao.owner and
ao.object_name = utp.table_name and
upper( ao.object_name ) = :object_name and
ao.object_type = 'PACKAGE' and
utp.privilege = 'EXECUTE' and
ao.status = 'VALID'
This has worked well and has saved us time on procedure privileges; I do realize now that I can also double check the all_tab_privs to check execute access as well.
The problem
Now my question is, how do I do something similar with tables? We ran into an issue where a certain user had SELECT privs on a table but not UPDATE/INSERT privs. How can I check for each of these privileges individually. I've looked into all_tab_privs but haven't found it shows me what I want. It has procedures I can execute but when I check to see if a known table is there it isn't. For example, I'll run the following
select * from all_tab_privs
where table_name = 'KNOWN_TABLE' and
grantee = 'CURRENT_USER'
and privilege in ( 'SELECT', 'UPDATE', 'INSERT' );
but instead of getting back 3 rows for a table I know 100% that I can already select/insert/update it returns nothing.
Any ideas? Thank you.
Disclaimer
I am aware that I could just try inserting/updating data and then deleting it but I'd rather not do this. I'd rather not leave any trace since these scripts will run periodically, should be repeatable, and shouldn't alter the state of any piece of data, even if it's just a sequence on the table.
Also, if you could provide a 'list' of possible queries that I can use to determine privileges that would be fine. For example, to determine if i have select access run query 1, 2 and 3. If either returns data then you have select privs and so on for insert/update.
This looks rather optimistic to me, as the role issue could get really complex, particularly if roles ever get password protected, and I'd never really trust the method 100% without actually trying the DML.
It might be more simple to try queries such as:
select count(*)
from schema_name.table_name
where 1=0;
insert into schema_name.table_name
select *
from schema_name.table_name
where 1=0;
delete from schema_name.table_name
where 1=0;
update schema_name.table_name
set column_name = column_name
where 1=0;
I believe that such queries would fail if no privileges were granted (no database handy to check it), and they would never modify any data.
By the way, the ANY privileges are generally regarded as a security problem, so you might like to fail the system if any user is granted them.
If you have privileges granted via roles, you need a more complicated check. The link in comments gives some queries to use to look at the wider picture, but if you want to check what the current user can see - as one of your queries suggests - then you can query the session_roles view to see what object privileges are currently available to your session via roles, in addition to directly-granted object privileges:
select atp.table_schema, atp.table_name, atp.privilege, atp.grantee,
'Direct' as grant_type
from all_tab_privs atp
where atp.grantee = user
union all
select atp.table_schema, atp.table_name, atp.privilege, atp.grantee,
'Via role' as grant_type
from session_roles sr
join all_tab_privs atp on atp.grantee = sr.role;
You can obviously add filters if you want to look at a specific object or privilege, and the grant_type pseudo-column is just for info - not really that useful since you can compare grantee with user to get the same info I suppose.
You might want to look at session_privs as well, to check your user has any system privileges you expect.
But if you want a single query to check the privileges for another user or several users at once, you'll need something more like the linked queries, and the privileges necessary to run them.
I ended up solving this problem using a multi-step approach based around different queries and the results they brought back. I'm executing all the queries with some PHP code so it wasn't 100% necessary that I only have big query to solve it all.
Additionally, our databases are split up physically and they are linked together through database links so I had to do some additional work to make sure that this privilege checking worked across database links.
Currently I'm only checking for SELECT, DELETE, UPDATE, and INSERT privileges; that is all I need really for now.
The procedure
Here is the general procedure in a nut-list.
Get a list of all the database links available to the user.
For the following steps, start with the current database we are logged into and then check each database link retrieved from step 1.
2a. Check to see if the table is visible using a database query.
2b. If the table is visible, check to see if any of the permission queries return that this user has access to the table.
The queries
Here are the queries for each of the steps above.
1 Database links
select db_link from all_db_links
2a Table Visibility
select * from all_tables%DB_LINK% where table_name = :table_name and owner = :owner
The %DB_LINK% above is replaced by #db_link where applicable. If we are checking the current connection then I remove it entirely. Remember, the queries are being executed by a PHP script so I can do some string manipulation on the string to either remove the %DB_LINK% for the current database or replace it with one of the database links we got from step 1.
2b. Users, Roles, Tables
There are 4 queries all together here.
/*****/
/* 1 */
/*****/
select *
from user_tab_privs%DB_LINK%
where
owner = :owner
and
table_name = :table_name
and
privilege = :privilege
/*****/
/* 2 */
/*****/
select * from user_sys_privs%DB_LINK% where privilege = :privilege
/*****/
/* 3 */
/*****/
select * from
(
select distinct granted_role from
(
select null linker, granted_role
from user_role_privs%DB_LINK%
union all
select role linker, granted_role
from role_role_privs%DB_LINK%
)
start with linker is null
connect by prior granted_role = linker
) user_roles join role_tab_privs%DB_LINK% rtab on user_roles.granted_role = rtab.role
where
owner = :owner
and
table_name = :table_name
and
rtab.privilege = :privilege
/*****/
/* 4 */
/*****/
select * from
(
select distinct granted_role from
(
select null linker, granted_role
from user_role_privs%DB_LINK%
union all
select role linker, granted_role
from role_role_privs%DB_LINK%
)
start with linker is null
connect by prior granted_role = linker
) user_roles join role_sys_privs%DB_LINK% rtab on user_roles.granted_role = rtab.role
where rtab.privilege = :privilege
Explanations
Database links
In the phpunit tests I pass in two things : table name and schema name ( owner ). However, because of the database links we have to explicitly check the other databases by using the #db_link in the queries. Otherwise I might report a table as being inaccessible when in reality it is accessible via the database link.
Table visibility
If the user can't see the table then there is no point in checking for privileges. Checking for privileges also prevents the case where a user has been given 'SELECT ANY TABLE' privileges but the table itself doesn't actually exist from causing an unwanted failure.
The band of 4 queries
As shown by other posters, a user can be given access to a table in many ways. Specifically, they can be given roles, and those roles can be given roles, and then those roles can be assigned access. Or the user can be given explicit access or generic access through system privileges.
Query 1
The first of the four queries checks to see if the user has been given explicit SELECT, DELETE, etc, privileges on the table. It's easy to understand and would ideally be all that's necessary
Query 2
The second checks to see if the user has been granted any system privileges like DELETE ANY TABLE, SELECT ANY TABLE, INSERT ANY TABLE, etc. These are not granted explicitly on a table but the user can perform any of the referenced actions on any table they have visibility.
Query 3
The third query will see if any of the roles that user has, either directly or indirectly, has been given explicit SELECT, DELETE, etc, privileges on the table. This is similar to query 1 except it's based on the roles given to the user, not the user.
Query 4
The fourth checks to see if any of the roles that user has, either directly or indirectly, has been given any system privileges like DELETE ANY TABLE, SELECT ANY TABLE, INSERT ANY TABLE, etc. This one is similar to query 2.
That's it! I chain these together and use the results returned from each to determine whether a user has the desired privileges or not.
Details worth mentioning
If a user has any privileges across db_link_1 it does NOT mean that they have the same privileges on tables they access across db_link_2. Most should know this but I wanted to make sure I stated it explicitly. For example, select privs on table 1 across db_link_1 does not imply select privs on table 2 across db_link_2.
I check each db_link one at a time. So first I start of with the database I'm connected to directly, no database link required for this. Then, if I can't find the table or don't have the privs on the table I move on to the next database link.
In queries 2 and 4, I use 'SELECT ANY TABLE', 'DELETE ANY TABLE', etc in place of the :privilege variable.
In queries 1 and 3, I use 'SELECT', 'DELETE', 'UPDATE', 'INSERT' in place of the :privilege variable.
Consider the case : In a database , I have two users A and B and their corresponding schema.
I want to know , How can I get the information : what permissions are there for USER A in Schema B .
Consider the case : We have two users and their associated scehmas. We have user A and user B. In A, say we have TB1 TB2, in B,say we have TBa, TBb. Now I want to know how can I find what privileges User A has on Schema B.
For example : User A is writing : select * from B.TBb This means USER A is accessing User B's table so , it shows he has SELECT Privilege. I want to know what all privileges User A has on Schema B.
Which query shall be executed to get the list of privileges that User A has on Schema B.
You can use these queries:
select * from all_tab_privs;
select * from dba_sys_privs;
select * from dba_role_privs;
Each of these tables have a grantee column, you can filter on that in the where criteria:
where grantee = 'A'
To query privileges on objects (e.g. tables) in other schema I propose first of all all_tab_privs, it also has a table_schema column.
If you are logged in with the same user whose privileges you want to query, you can use user_tab_privs, user_sys_privs, user_role_privs. They can be queried by a normal non-dba user.
Use example with from the post of Szilágyi Donát.
I use two querys, one to know what roles I have, excluding connect grant:
SELECT * FROM USER_ROLE_PRIVS WHERE GRANTED_ROLE != 'CONNECT'; -- Roles of the actual Oracle Schema
Know I like to find what privileges/roles my schema/user have; examples of my roles ROLE_VIEW_PAYMENTS & ROLE_OPS_CUSTOMERS. But to find the tables/objecst of an specific role I used:
SELECT * FROM ALL_TAB_PRIVS WHERE GRANTEE='ROLE_OPS_CUSTOMERS'; -- Objects granted at role.
The owner schema for this example could be PRD_CUSTOMERS_OWNER (or the role/schema inself).
Regards.
Login into the database. then run the below query
select * from dba_role_privs where grantee = 'SCHEMA_NAME';
All the role granted to the schema will be listed.
Thanks Szilagyi Donat for the answer. This one is taken from same and just where clause added.
How to get list of all Materialized Views.?
Try this:
SELECT *
FROM all_snapshots;
Instead of all_snapshots you can also use the all_mviews view.
select * from all_mviews;
or
select * from dba_mviews;
I never use all_snapshots before.
Here is another way to do:
select * from all_objects where OBJECT_TYPE='MATERIALIZED VIEW';
Actually ALL_MVIEWS and ALL_SNAPHOTS displays only the views the user has granted access on. To see all views in a database you must query DBA_MVIEWS or DBA_SNAPHOTS. You need special privileges or roles to query this view like the system privilege SELECT ANY DICTIONARY or the role SELECT_CATALOG_ROLE.
A similar statement holds for other ALL_ and DBA_ views.