I want to execute code on user IDK:
CREATE OR REPLACE TRIGGER sal_trig
AFTER UPDATE OF status ON TAB1
FOR EACH ROW
WHEN (new.status = 'ZAK')
CALL log_sal(1, 5, 8);
I have following grants:
GRANT CREATE PROCEDURE TO IDK;
GRANT CREATE SEQUENCE TO IDK;
GRANT CREATE TABLE TO IDK;
GRANT CREATE TRIGGER TO IDK;
GRANT CREATE TYPE TO IDK;
GRANT UNLIMITED TABLESPACE TO IDK;
GRANT SELECT ON TAB1 TO IDK;
What grants i need more?
I won't get update/delete/insert on TAB1.
I am getting error: not sufficient privileges.
I created procedure from user IDK:
CREATE OR REPLACE PROCEDURE log_sal (
emp_id NUMBER,
old_sal NUMBER,
new_sal NUMBER
)
AS LANGUAGE JAVA
NAME 'CaseWatch.logSal(int, float, float)';
According to your comments the TAB1 table created by different User, so the table is in a different schema, this is the main key.
When you want to grant privileges to create a trigger on a table in different schema then you need to use:
GRANT CREATE ANY TRIGGER TO IDK;
CREATE TRIGGER => in fact giving permission to create a database trigger in the grantee's schema, in your case if TAB1 created by IDK then this privilege is enough.
Regarding the CREATE ANY TRIGGER here you can find some more interesting info:
https://docs.oracle.com/cd/B19306_01/server.102/b14200/statements_9013.htm
Grant create any trigger vs grant create trigger
Related
I have a table_aa created by ROLE_A under my_database.shema_1. Now, I have another ROLE_B, which has CREATE TABLE and USAGE privilege on my_database.shema_1, as well as SELECT on tables under my_database.shema_1. Then, is ROLE_B able to insert data into table_aa, which is owned and created by ROLE_A?
I understand since table_aa's ownership is ROLE_A, so ROLE_B can't drop table_aa. But could ROLE_B write into table_aa?
I'm new to the snowflake. Any ideas?
Your understanding is correct. ROLE_B can't drop/insert into table_aa since it is owned by ROLE_A.
I understand where your confusion lies. In your case, since ROLE_B has CREATE TABLE and USAGE SELECT on tables privilege on my_database.shema_1, it is not sufficient for this role to insert or drop tables owned by other roles. Now, since ROLE_B has the CREATE TABLE privilege, any new table created by this role, will be owned by ROLE_B and likewise, ROLE_A can't insert/drop the tables owned by this role unless specific permissions are given.
In your case, as suggested by #srinath you need to grant INSERT privilege to ROLE_B
grant insert on table my_database.shema_1.table_aa to role ROLE_B;
For an object owned by a role, the owner role has to grant necessary privileges to the objects in order to perform specific operations using another role.
To verify what all the privileges a role has, run show grants to role; similarly to check all the privileges a particular table has been assigned run show grants on table my_database.shema_1.table_name; This will show all the privileges the table has and assigned to which role.
Refer to snowflake-access-control-model and security-access-control-privileges for more clarifications
You will need to provide insert privilege to Role_B on table_aa to be able to write to it.
I have a user who is a member of the db_DataReader role (and no other roles apart from public), and has been granted explicit execute permission on a scalar function, but when they use the function
select hbp_plant.CatComments(42)
they get
The EXECUTE permission was denied on the object 'CatComments', database 'HBDevSIMCOA', schema 'HBP_Plant'*.
How do I give them permission to call the function without giving them any ability to modify the database?
Does the function access tables in different schemas, other than hbp_plant?
Instead of adding the db user to the db_datareader role, grant SELECT (for the whole db) and execute permissions on the function:
--db user = myreadonlyuser
grant select to myreadonlyuser; --can read from tables, table valued functions, views..in all schemas
grant execute on hbp_plant.CatComments to myreadonlyuser;
Give Exec Permission on tablename. Try this.
USE HBDevSIMCOA;
GRANT EXEC ON hbp_plant.CatComments TO PUBLIC
you can refer below link
The EXECUTE permission was denied on the object 'xxxxxxx', database 'zzzzzzz', schema 'dbo'
Try this:
CREATE SCHEMA [hbp_plant];
GO
CREATE FUNCTION [hbp_plant].[CatComments] (#A INT)
RETURNS INT
AS
BEGIN
RETURN #A
END;
GO
CREATE USER [StackOverflow] WITHOUT LOGIN;
-- do not work
EXECUTE AS USER = 'StackOverflow';
SELECT [hbp_plant].[CatComments](5) ;
REVERT;
GRANT EXECUTE ON [hbp_plant].[CatComments] TO [StackOverflow];
-- work
EXECUTE AS USER = 'StackOverflow';
SELECT [hbp_plant].[CatComments](5) ;
REVERT;
DROP USER [StackOverflow];
DROP FUNCTION [hbp_plant].[CatComments]
DROP SCHEMA [hbp_plant];
I am not a DBA, but have been asked to help set up a teaching database for some internal company SQL classes. I am using an Azure SQL Server database where each student needs to be able to create tables, views and stored procedures for themselves but not see any of the other students' work. I am unable, due to cost constraints, to create an Azure DB for each student and load it with the raw data, so I am trying to do it all in one DB.
Here was my idea:
Create a schema for each student and give them permissions to write
to it.
Give them permissions to read from the dbo schema where the
raw data will be stored, but not write to it (I dont want to give them the opportunity to overwrite the raw tables).
Hide all the other students schemas so that the student can only see their
tables/views/sprocs and those in the dbo schema.
I have been able to create logins and users and schemas and give read permissions to dbo schema, but i can't give the student full control over their own schema.
What i need advice on is, how can i set up the database to let each student have their own schema with write access, but have read-only access to the dbo schema? It seems like i can lock down the students schema, but cant give them write access to it without write access to the entire database. Is there a way to separate them this way?
Also, is there a better way to do what I want with regards to separating students' environments on the same database?
This is what i have tried so far:
USE MASTER
CREATE LOGIN student1 WITH PASSWORD = 'T3mpSuperSecret!';
USE class_DB
CREATE USER student1 FOR LOGIN student1;
CREATE SCHEMA st1 AUTHORIZATION student1;
GRANT SELECT ON SCHEMA :: dbo TO student1
GRANT CONTROL ON SCHEMA :: st1 TO student1
I then try to select one of the base tables from dbo into the new schema:
select *
into st1.inventories
from dbo.inventories
I get:
Msg 262, Level 14, State 1, Line 1
CREATE TABLE permission denied in database 'class_DB'.
It looks like create table permissions is on a DB level, not the schema level. Is there a way to authorize create table permissions on the schema level?
I hope this all makes sense. Again, I am not a DBA, so any help would be appreciated.
Thanks!
Granting CREATE TABLE, and other permissions doesn't do anything is that USER doesn't also have the ALTER permission. As such, all you need to is GRANT the USER the CREATE TABLE, CREATE VIEW, etc permissions on their specific schema, and then SELECT on the dbo schema.
This uses with WITHOUT LOGIN as an example, as I don't have the LOGIN objects, but this demonstrates the granted, and implicitly denied, permissions:
CREATE DATABASE SampleDB;
GO
USE SampleDB;
GO
CREATE TABLE dbo.SomeTable (SomeID int IDENTITY);
INSERT INTO dbo.SomeTable
DEFAULT VALUES;
GO
CREATE USER student1 WITHOUT LOGIN;
GO
CREATE SCHEMA st1 AUTHORIZATION student1;
GO
GRANT SELECT ON SCHEMA::dbo TO student1;
GRANT CREATE TABLE, CREATE VIEW, CREATE FUNCTION, CREATE PROCEDURE TO student1;
GO
CREATE USER student2 WITHOUT LOGIN;
GO
CREATE SCHEMA st2 AUTHORIZATION student2;
GO
GRANT SELECT ON SCHEMA::dbo TO student2;
GRANT CREATE TABLE, CREATE VIEW, CREATE FUNCTION, CREATE PROCEDURE TO student2;
GO
EXECUTE AS USER = 'student1';
GO
CREATE TABLE st1.TestTable (ID int);
INSERT INTO st1.TestTable
SELECT SomeID
FROM dbo.SomeTable;
GO
SELECT *
FROM st1.TestTable;
GO
REVERT;
GO
EXECUTE AS USER = 'student2';
GO
CREATE PROC st2.TestProc AS
BEGIN
SELECT *
FROM st1.TestTable;
END;
GO
EXEC st2.TestProc; --fails
GO
CREATE TABLE st1.TestTable (ID int); --fails too
GO
REVERT;
GO
USE master;
GO
DROP DATABASE SampleDB;
Just trying to play around with permissions, I want to grant CREATE table permission to user but not ALTER or DROP. Moreover user should be able to create table only(no stored proc, no function)
grant alter on schema::dbo to demo_db_user
grant create table to demo_db_user
By using above command, user is able to alter table as well.
You could write a DDL-Trigger and prevent the ALTER TABLE if the current User is not member in a specific role (or whatever), similar like this (untested):
CREATE TRIGGER [ddl_tr_prvent_alter_table] ON DATABASE
FOR alter_procedure
as
begin
if User_Name() <> 'dbo'
RAISERROR ('go ahead, you must not change a table', 16, 1);
end
I have 2 schemas and one of the objects in the first schema needs to access an object in the other schema. For example:
CREATE VIEW I.ITest
AS
SELECT 1 as TestColumn
GO
CREATE VIEW O.OTest
AS
SELECT * FROM I.ITest
GO
EXEC ('SELECT * FROM O.OTest') AS USER = 'TestUser'
DROP VIEW O.OTest
DROP VIEW I.ITest
In the above example, TestUser only has access to the 'O' Schema. So the select itself works fine, but because the view is doing a select from another schema 'I' then it fails with the error:
The SELECT permission was denied on the object 'ITest', database 'MyDB', schema 'I'.
To get around this I can give the 'O' schema permission to access the 'I' schema, but this doesn't sound right and looks to be bypassing the schema permissions.
What can be done? Am I doing this all wrong? Whats the best practice in this scenario?
Thanks
UPDATE: My schemas were owned by different db roles so I got around this problem by simply changing the owner of both to dbo and then giving the db role permission to access the schema. This meant that the owner dbo could see everything and I could then give specific permission to the db role only and the rest of the db objects were not available unless via this schema. Thanks for your help
You should wrap the selection of data from the view on the "other" Schema, within a stored procedure. Then grant execute rights on the stored procedure. Although the user will not have direct access to the view they are permitted access via the stored procedure.
Here is an example walkthrough for you demonstrating the security principles as work:
USE DATABASE SANDBOX;
--Create Logins
CREATE LOGIN UserOne WITH Password='Hello123';
CREATE LOGIN UserTwo WITH Password='Hello123';
--Create Database Users
CREATE USER UserOne;
CREATE USER UserTwo;
--Create the Test Schemas
CREATE SCHEMA SchemaOne AUTHORIZATION UserOne;
CREATE SCHEMA SchemaTwo AUTHORIZATION UserTwo;
--Create a View on SchemaOne
CREATE VIEW SchemaOne.ViewOne
AS SELECT 1 as TestColumn;
--Create a View on SchemaTwo
CREATE VIEW SchemaTwo.ViewTwo
AS SELECT * FROM SchemaOne.ViewOne;
--Test that the SchemaOne
EXEC('select * from SchemaOne.ViewOne') AS USER = 'UserOne'
--1
EXEC('select * from SchemaTwo.ViewTwo') AS USER = 'UserOne'
--The SELECT permission was denied on the object 'ViewTwo', database 'SANDBOX', schema 'SchemaTwo'.
--Create a stored procedure to safely expose the view within SchemaTwo to UserOne who's default Schema is
--SchemaOne.
CREATE PROCEDURE SchemaTwo.proc_SelectViewTwo
AS
select * from SchemaTwo.ViewTwo;
--Grant execute rights on the procedure
GRANT EXECUTE ON SchemaTwo.proc_SelectViewTwo TO UserOne;
--Test the
EXECUTE AS LOGIN='UserOne';
Exec SchemaTwo.proc_SelectViewTwo;
revert;
An alternative approach as suggeted in my comments would be to use a Database Role to control access to multiple schemas. Using the principals as defined in the solution above, you could use Database Roles like so:
EXEC sp_addrole 'CrossSchemaRole';
EXEC sp_addrolemember 'CrossSchemaRole','UserOne';
GRANT SELECT ON SCHEMA::SchemaOne TO CrossSchemaRole;
GRANT SELECT ON SCHEMA::SchemaTwo TO CrossSchemaRole;
EXECUTE AS LOGIN='UserOne';
select * from SchemaTwo.ViewTwo;
revert;
Some suggested further reading:
Securing SQL Server
SQL Server Permission Hierarchy
White Paper: Security Overview for
Administrators
Surely you give permissions to users not objects and that's it. If you or the owner of the other schema wants to allow other users to access objects (whether they are tables, views or whatever) within it then it is up to the owner of the other schema. Just because you as the developer can write a procedure that accesses objects in other schemas it does not follow that anyone running your procedure should be allowed to do so too. Roles are the way to go.