Custom roles don't behave like default roles in terms of inheritance? - sql-server

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.

Related

Snowflake grants to role keeps resetting everyday

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

Setting System Wide Variables in Snowflake

I'm interested in finding a method where a system wide variable can be written onto the Snowflake Account, and used in a view so that users can see the underlying DDL, but not know the value used in a particular function.
At the moment this is done by making these a "Secure" View, but that limits almost everyone from seeing the underlying DDL (which would be helpful to our users and admins).
I'm wondering if there is a way to set a System Wide Variable, and use that in the DDL.
Example:
SET SYSTEM VARIABLE variable_name = 'some_value';
CREATE VIEW catalog.schema.tablename AS
SELECT TRANSLATE(COLUMN_NAME, '0123456789', variable_name) AS NEW_COLUMN_NAME
FROM <FULL SOURCE TABLE NAME>
WHERE <WHATEVER CONDITIONS APPLY>;
I have found setting variables on a session, and I know I can see / change Account Parameters. But can I create something like Account Variables?
Function has two privileges on it - OWNERSHIP and USAGE. If you don't give either of these function privileges to the viewer of the view, but you give the viewer SELECT privileges on the view, they will be able to see the DDL of the view, but won't be able to see the details of the UDF. Then you can store values in your UDF that you don't want other people seeing. I'll post code for this in just a second.
--Something like this to test it out from scratch. You must have accountadmin for this to work:
--use role accountadmin:
--create a database called demo_db;
--create a role called owner_demo_db and grant it usage, monitor, and create schema; also give it usage on a warehouse;
--create a user called demo_db_user. give them ownership on demo_db;
--create a role called reader_demo_db;
--assign the "reader" and the "owner" role to demo_db_user;
--as the owner_demo_db role, create the following:
use role owner_demo_db;
--The role owner_demo_db will own this function
create function pi_udf()
returns float
as '3.141592654::FLOAT'
;
--The role owner_demo_db will own this view
create view MyView as
select 'some_value' AS someval
, pi_udf() pi_val;
--Because owner_demo_db owns the view, they can grant select to the reader role to the view
grant select on view demo_db.demo_schema.MyView to reader_demo_db;
--Show functions and views and you'll be able to see both.
show functions;
show views;
--Show functions and views as reader_demo_db, and you'll only be able to see DDL for the view b/c you don't have a privilege on the function
use role reader_demo_db;
show functions;
show views;

What permissions to I need to use User Defined Table Types

Background:
I have two accounts for the same database one "master" account and another (sub) account which I use for my website to use to connect to the server so I can manage what the user can and cannot do. A lot of the permissions on this account were already on there before I got access to it so I don't know what exactly all the permissions are, except the ones I have managed.
There is a user defined table type that some one else created, dont ask me why they did,
CREATE TYPE [dbo].[AffectedServiceList] AS TABLE(
[AffSerName] [nvarchar](200) NULL
)
GO
This type is used in a stored procedure like so
ALTER PROCEDURE [dbo].[Contractsetup] #OtherParams, --Easier than typing them all
#list dbo.AFFECTEDSERVICELIST READONLY
The master account can execute and modify this procedure perfectly but the sub account cannot run or modify this stored procedure while the affectedservicelist type is used as it gets the error
Cannot find the type 'AffectedServiceList', because it does not exist
or you do not have permission.
I have tried doing this grant execute on type::dbo.AFFECTEDSERVICELIST to subaccount
But it still returns the same error that about the permissions. I have eliminated it to the the permissions as when I try and modify on the master account I just get
Command(s) completed successfully.
To use User Defined Table Type you need EXECUTE or CONTROL permission on it.
Your code
grant execute on type::dbo.AFFECTEDSERVICELIST to subaccount
is correct.
What is missing here is REFERENCES permission:
grant references on type::dbo.AFFECTEDSERVICELIST to subaccount
this is need to be able to reference this type in the code.
To only be able o create a proc using UDT, you only need REFERENCES permission. EXECUTE or CONTROL is needed to be able to execute the code(proc)
After doing a bit more digging the permission I needed to add was not execute it was control.
So instead of doing this;
grant execute on type::dbo.AFFECTEDSERVICELIST to subaccount
I actually needed to do this;
grant control on type::dbo.AFFECTEDSERVICELIST to subaccount

Azure DB - How to give 1 user read-only permission for 1 table

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'

sybase privileges grant from one shcema to another

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).

Resources