I have two schemas where number of functions created there. I wanted to grant function to ROLES.
Also wanted to FUTURE GRANT on functions to ROLES.
Do i need to create grant command for each functions. Also do we have future grants on functions?
Thanks
Ashok
First, you can grant all on future functions.
grant all on future functions in schema "myDB"."mySchema" to role MyRole;
Then, you can generate the SQL to grant for existing functions:
show functions in schema "MyDB"."MySchema";
SELECT 'grant all on function "' || "name" || '" to role MyRole;' FROM table(result_scan(last_query_id())) where "is_external_function" = 'Y'
You may more details here in Snowflake documentation:
https://docs.snowflake.com/en/sql-reference/sql/grant-privilege.html#
https://docs.snowflake.com/en/sql-reference/sql/grant-privilege.html#future-grants-on-database-or-schema-objects
Related
I have created a new user 'u' using my 'security_admin' role, and assigned role 'r' (which already has some select/usage permission on few tables) to the user. Now I want add more permissions to the role. I have ran below statement:
grant select on all tables in schema db_name.schema_name to role r;
The above statement gives necessary permission to the user 'u', i have checked with show grants to role r statement. However the granted permission is valid only for one day, the next day the user does not have the permission that is granted using above statement. It keeps happening for sometime. I do not know what the problem is. I do not have any automated SQL script to recreate users & grants daily.
If you could share the actual error message you get, that would be helpful for us to understand where the problem lies. But I suspect that it's just a case of not having access on FUTURE TABLES (tables that has been created after the grants was applied).
These commands should cover you:
use role securityadmin;
grant usage on database db_name to role r;
grant usage on schema db_name.schema_name to role r;
grant select on all tables in schema db_name.schema_name to role r;
grant select on future tables in schema db_name.schema_name to role r;
One plausible scenario is that tables are recreated with CREATE OR REPLACE TABLE command. It could be checked using query history view.
SELECT *
FROM snowflake.account_usage.query_history
WHERE DATABASE_NAME = 'DATABASE_NAME_HERE'
AND QUERY_TEXT ILIKE '%CREATE%OR%REPLACE%TABLE%'
ORDER BY START_TIME DESC;
In such case the permissions may not be preserved, unless specyfing COPY GRANTS option.
Optional parameters:
COPY GRANTS
Specifies to retain the access privileges from the original table when a new table is created using any of the following CREATE TABLE
variants:
CREATE OR REPLACE TABLE
CREATE TABLE … LIKE
CREATE TABLE … CLONE
In sql server, suppose user is member of db_owner, then, SELECT IS_MEMBER("DB_DATAREADER") returns true.
Where as if I create a new custom db role, checkmark db_datareader, now the above sql query returns false.
Custom roles don't behave like default roles in terms of inheritance?
They do. Here's a demo showing that:
-- setup
CREATE USER TestUser WITHOUT LOGIN;
GO
CREATE ROLE TestRole;
ALTER ROLE db_datareader
ADD MEMBER TestRole;
ALTER ROLE TestRole
ADD MEMBER TestUser;
GO
-- demo
EXECUTE AS USER = 'TestUser';
GO
SELECT name
FROM sys.user_token
WHERE type = 'ROLE'
GO
REVERT;
That said, this statement you made:
create a new custom db role, checkmark db_datareader
suggests that you may have made db_datareader a member of your role. In practical terms, that would mean that members of the db_datareader role would also get membership in your user-defined role. Or, looking at the UI, perhaps you made your user-defined role the owner of the db_datareader schema. Either way, not what you were intending to do.
In order to corroborate what's happening, do what you're doing through the GUI but rather than hitting "OK", hit the "Script" button near the top of the window. That will produce the T-SQL that hitting OK would have applied for you.
I want to create a function once and have it be available everywhere on the account.
I don't want to have to specify fully-qualified name in all usages.
And I don't want to create it in every database, and possibly on every schema.
Ideally, it is accessible across the account without specifying database / schema.
For example, suppose I want a case-insensitive contains function available everywhere.
CREATE OR REPLACE FUNCTION udf_icontains(val varchar, search_pattern varchar)
RETURNS BOOLEAN
AS
$$
contains(lower(val), lower(search_pattern))
$$;
It seems I must create it on every database and every schema in order to reference without FQN.
You can create it in a single database and schema, grant public access, and then reference it in queries using its fully-qualified name (db.schema.udf...) from everywhere.
Just create a public database with a name like global or account (we call ours utils) with a public schema called udfs.
You already have a udf_ prefix in the name of your UDF; global.udfs.icontains is not much longer to type than udf_icontains.
CREATE DATABASE IF NOT EXISTS global;
CREATE SCHEMA IF NOT EXISTS global.udfs
GRANT USAGE ON DATABASE global TO ROLE public;
GRANT USAGE ON SCHEMA global.udfs TO ROLE public;
GRANT USAGE ON FUTURE FUNCTIONS IN SCHEMA global.udfs TO ROLE public;
GRANT USAGE ON ALL FUNCTIONS IN SCHEMA global.udfs TO ROLE public;
I've been reading many answers but I am too weak at TSQL to filter out what I need.
I created a contained user for 1 DB...
CREATE USER appuser WITH PASSWORD = 'strongpwd';
So I need to allow a user in to read only the contents of 1 table - tableA (there are others in the DB) and do absolutely nothing else in the DB.
I do not want to affect any other users. I just want the user to be able to access the DB via say SSMS, see only tableA (well this is not that important), read it.
There are two ways one is to directly grant explicit SELECT only on Table 1 and the second one is to create a role, grant SELECT to role and addd the user to the role. Typically second way is the preferred way and can be done as below
CREATE ROLE [role_name]
GRANT SELECT ON [Table] to [role_name]
EXEC sp_addrolemember '[role_name]', 'appuser'
I have 2 schemas database1#server and database2#server.
I want to know how to grant priveleges for database2 to read from database1.
example executing in database2:
select * from database1..table1
You will have to make sure the user in database2 is added to database1 (sp_adduser or sp_addalias).
You can find your current user by doing select user_name() and get a list of users within a database by executing sp_helpuser in that database.
Assuming we have db_user1 and dbuser2, we would add the alias like this:
use database1
go
sp_addalias db_user2, dbuser1
go
From that point forward, when db_user2 is accessing database1, it will be with db_user1's credentials, rights and privileges.
If you add the user, instead of adding the alias, then you will have to grant privileges for tables in the schema to the user (or group that the user is a member of).