I am working on the application which works on Oracle. For some kind of logic I need to get the list of tables from the given db user with the specified schema. In my case, I have a user which have granted access of the given schema. So when my code creates connection using the given credential and tries to fetch the tables from the following query, its return table list.
SELECT * FROM dba_objects where owner ='schema' and object_type = 'TABLE'
The above query was working with user having grant all privileges
but when I did try with limited permission, it is throwing error msg.
ORA-00942: table or view does not exist
00942. 00000 - "table or view does not exist"
For the secondary user, from which our code is creating connection has granted permissions by following query
create user johnsmith identified by Passw0rd;;
grant connect to johnsmith ;
grant select any table to johnsmith ;
grant UPDATE any table to johnsmith ;
grant DELETE any table to johnsmith ;
grant INSERT any table to johnsmith ;
Which permission should I grant to user to have access on the following system tables...?
dba_objects
user_constraints
user_cons_columns
USER_TABLES
all_tab_cols
and also allow to access dbms_metadata.get_dependent_ddl() method
With the O7_DICTIONARY_ACCESSIBILITY initialisation parameter set to false, which is the default, then:
System privileges that provide access to objects in other schemas do not give other users access to objects in the SYS schema. For example, the SELECT ANY TABLE privilege allows users to access views and tables in other schemas, but does not enable them to select dictionary objects (base tables of dynamic performance views, regular views, packages, and synonyms). You can, however, grant these users explicit object privileges to access objects in the SYS schema.
So you can either grant select privileges on the specific views you need:
grant select on sys.dba_objects to johnsmith;
and the same for other views; or if you need them to have wider access to the SYS schema objects you can give them that with a role:
grant select_catalog_role to johnsmith;
though the principle of least privilege should always apply, so this may be overkill and potentially expose things you don't want that user to be able to see.
You don't need to grant anything for the user to be able to query user_* views. If you meant the DBA equivalents of those - e.g. dba_tables - then grant them as for dba_objects above; or they woudl be included in select_catalog_role. But again, only grant what is actually needed.
Either way, for dbms_metadata you can just grant privileges on that package too (you can't grant privileges on individual procedures in a package):
grant execute on dbms_metadata to johnsmith;
or - again probably much more than actually needed, and potentially much more dangerous that the select role:
grant execute_catalog_role to johnsmith
Related
I want to create a role on snowflake limited only to one database and one schema and give there a read access on all tables.
I create a role, grant:
grant usage on database1,
grant usage on database1.schema1,
grat select on all tables in database1.schema1,
and I grant usage and operate on one warehouse1.
However, additionally to this I am seeing also other databases and other schemas with this role, despite no grants were added, also there is additional warehouse to warehouse1.
How I can limit access with this role and not see something that appear as default
'databases' even for roles with no grants?
Regards
P
You will be able to find out what the role can and cannot do.
Check the which users and/or roles are granted the privilege of the role:
show grants of role ;
Then check what privileges were given to the role:
show grants to role ;
All the users are granted the PUBLIC role. Hence, never grant any privileges to the PUBLIC role, as this simply means giving the whole world access to a database, schema and tables/views etc.
I have a PostgreSQL DB user "limited_user" and want to give SELECT permission on one table ONLY.
GRANT CONNECT ON DATABASE "db1" TO limited_user;
GRANT SELECT ON TABLE users to limited_user;
What happens is that when I try \dt , the user can see all the other tables in this db1, while he can perform SELECT operation to table "user" as I gave permission. How can I revoke access access to the user so that he can not see other tables and just one table?
You can't, at least not in any straightforward way that I am aware of.
Tables exist within the schema namespace, and schemas exist within the database. To give access to a user on a particular table means you must also give that user the USAGE permission on the schema to which the table belongs. USAGE does not grant permissions on the tables themselves, only the the schema in question. But table definitions are part of the schema, so USAGE does allow the user to see table names (and the columns too).
But if there are other tables in the same schema, the user will not be able to SELECT from those tables unless you also GRANT SELECT on those tables, even though they will be able to see that they exist.
This answer gives a pretty clear explanation of the permission system.
Edit to add:
One way to achieve a similar outcome would be like this (using psql):
sec_schema=# REVOKE ALL ON ALL TABLES IN SCHEMA sec_schema FROM restricted_user;
REVOKE
sec_schema=# REVOKE USAGE ON SCHEMA sec_schema FROM restricted_user;
REVOKE
sec_schema=# CREATE SCHEMA new_schema;
CREATE SCHEMA
sec_schema=# GRANT USAGE ON new_schema TO restricted_user;
GRANT
sec_schema=# CREATE VIEW new_schema.secret_view AS SELECT * from sec_schema.secret_table;
CREATE VIEW
sec_schema=# GRANT SELECT ON new_schema.secret_view TO restricted_user;
GRANT
This will remove all access to the schema sec_schema for user restricted_user, but then creates new_schema and new_schema.secret_view which is a cover view over sec_schema.secret_table. After the GRANT SELECT, the user will be able to read the data from table sec_schema.secret_table through the view, but they will not be able to see any objects in sec_schema.
Fundamentally I want
my "DBA" user; the original account which has the SYSADMIN and ACCOUNTADMIN roles, to be able to see any object in the database as well as its data. It seems that at least at the level of ACCOUNTADMIN I should be able to do this.
a "power" user; via a role (dr_uce_role) I can assign at a database level where the user can do virtually everything within a database.
I thought I had made the power user role with the following code:
--grant power to engineer
grant all privileges on database dr_ev to dr_uce_role;
grant all privileges on all schemas in database dr_ev to dr_uce_role;
grant all privileges on all tables in schema dr_ev.public to dr_uce_role;
grant all privileges on all views in schema dr_ev.public to dr_uce_role;
grant select on future tables in schema dr_ev.public to dr_uce_role;
grant select on future views in schema dr_ev.public to dr_uce_role;
grant all privileges on all tables in schema dr_ev.stg to dr_uce_role;
grant all privileges on all views in schema dr_ev.stg to dr_uce_role;
grant select on future tables in schema dr_ev.stg to dr_uce_role;
grant select on future views in schema dr_ev.stg to dr_uce_role;
This user then created objects in the schemas. However my "DBA" user at SYSADMIN could not see the objects at all. With role ACCOUNTADMIN the user can see the objects, but not query them. My understanding is that ACCOUNTADMIN is the top level account, and can take ownership of these objects anyway, so if this is supposed to be a security feature I don't really understand how it is providing much protection as it can always steal ownership?
I tried changing ownership of an object as ACCOUNTADMIN to SYSADMIN, to find it had a blocking privilege;
grant ownership on dr_ev.stg.load_opportunity to sysadmin;
SQL execution error: Dependent grant of privilege 'DELETE' on securable 'DR_EV.STG.LOAD_OPPORTUNITY' to role 'DR_UCE_ROLE' exists. It must be revoked first. More than one dependent grant may exist: use 'SHOW GRANTS' command to view them. To revoke all dependent grants while transferring object ownership, use convenience command 'GRANT OWNERSHIP ON TO REVOKE CURRENT GRANTS'.`
I tried taking ownership with
grant ownership on all tables in schema dr_ev.stg to sysadmin revoke current grants;
which did work - although it left my power user unable to see the objects. So I granted them back with
grant all privileges on all tables in schema dr_ev.stg to dr_uce_role;
However I want my power user to be able to create or replace this table. I believe this requires the DROP TABLE privilege, although apparently my power user grants do not provide it, and I am unclear on how I should be providing it?
I will not say I have the greatest understanding of Snowflake privileges and am wondering if the statements above like grant all privileges on all tables in schema do not live at the schema level to blanket apply to all tables, but actually sets object level permissions and my original approach has simply been too granular as I do not actually wish to manage anything at object level. That being said, I am unclear in the doc how to manage at a higher level than object anyway if the statement is actually just a shortcut to set many object privileges. How can I accomplish my original goals?
The best practice for a situation like this is to grant all of your custom roles to the SYSADMIN role. This allows the sysadmin to do everything a SYSADMIN can do plus everything that all of the other roles can do. You have a lot of questions in your post, but I think this resolves many of them.
The way I did was to create a super role 'superole' and granted sysadmin, securityadmin and accountadmin to that role. I then attached the superrole to whoever I wanted to be my DBA...
I need to allow certain user access to only specific views and tables. I have tried following so far
Created a user ex_user
Created a role rviewonly
deny view definition to rviewonly;
Then I executed this sql
GRANT SELECT ON vwBI_PEOPLE TO rviewonly
It seems to work, and this ex_user can do a select command on it however I do not see this vwBI_PEOPLE in list of views in Management Studio. There are about 50 views that I have to give this user access to along with about 40 different tables - I want the user to be able to see the available views and tables in Management Studio's Object Explorer
Because you have denied view definition at the database level (no object specified) to the role/user, this trumps any grant view definition on ... that you may make on an individual object. Grant select on ... will also allow view definition on that object without having to specify grant view definition.
I recommend revoking view definition at the database level:
revoke view definition to rviewonly;
And simply let your grant select on statements do the work for you. You shouldn't have to rerun them again after running the above revoke. view definiton by itself would be good for giving a user/role access to metadata, but not data.
Note that any deny will always trump a grant including the cases where you deny a role access but grant the user access or vice-versa.
I just verified this on a SQL Server 2008 R2 dev box. I'm not sure if any settings exist that might alter this behavior for your instance.
I had the same question before. I, instead of using a role, just granted select on the user itself. This is something handy for multiple table permission granting:
SELECT 'GRANT SELECT ON '+name+' TO ex_user;'
from sysobjects
where name in (
'[Enter table]',
'[names here]',
'[in a list]',
'[to grant permissions]'
)
Then copy all the results, throw it in a query, and run it. Especially handy if all the tables you want to grant access to are prefixed with the same grouping of letters.
Example: You can just change the above query's where clause to be where name like 'TST_%', if all the tables/views you're granting start with "TST_".
You need to add ex_user to rviewonly role sp_addrolemember:
EXEC sp_addrolemember rviewonly, [ex_user];
Then use revoke instead of deny view definition to the role:
revoke view definition to rviewonly;
Is there a way I can give developers permission to grant a user permissions over objects without giving them the option to create users or functions?
I'm trying to limit developers permissions, I recently found out that developers had db_owner permissions in dev and prod environments! So I'm doing my best to stop this madness.
Any good article about this matter?
You can make them members of the "db_securityadmin" database role
As said, if someone could hand out permissions, they could hand out permissions to themselves (or a dummy account). I'm not sure if there is a trick in SQL Server to provide "give user permissions less then me".
The way I would do it is with stored procedures.
Create a stored procedure that gives a specified user a specific right or set of rights (those rights are the ones that regular users are allowed to have). Then give the developers execute access to this stored procedure. In effect you use stored procedures to create a limited version of GRANT, while keeping the full GRANT command to yourself.
If someone can give someone else permissions, he can also give himself the permission to do what he wants. So what is this good for? Probably I don't understand your situation.
Owners of objects can grant permissions on those objects. Provided your developers don't need to grant things like CREATE TABLE rights, you might be able to give them ownership of the objects that you want them to grant permission on.
As Stefan said, giving them grant permissions would effectively give them all permissions, since if they want to do something all they have to do is grant themselves the permissions to do it.
Rather than considering the developers the enemy, though, you may want to consider giving the developers a second user account that's used to administer the database. It's pretty common not to give developers ANY permissions to production, at least on their development account.
Setting permission on objects like stored procedures can be accomplished with "GRANT EXECUTE ON . to ;
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). The EXECUTE AS can be added to stored procs, functions, triggers, etc.
Add to the code as follows right within the Stored Procedure: 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... imperonate CALLER , which will enable to module to take on the permissionsof 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.
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 NO 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.
I've found that the most dangerous aspect of the db_owner role is that if you issue a deny on a permissions, then the members of the role can grant it back to themselves. I've just started reading about this and I'm testing this
Create role db_ControlDatabase
grant control to db_ControlDatabase
deny backup database to db_ControleDatabase
alter role db_ControlDatabase add member TestUser
So far, I've found that the subject TestUser has permissions without being able to add or remove members of the fixed database roles. You should be able to deny whatever you need at this point like backup certificate, backup master key, etc.
Here is a list of permissions that can be denied or granted: