For our backup software I'm trying to add a check if the user has enough permissions to create a backup.
When I create a login Test for a database and give it the db_backupoperator role for that database, how do I check for that role?
I tried:
SELECT name as 'DatabaseName', has_dbaccess(name) as 'HasAccess' FROM sys.databases
This is always 0 for each database (except master, tempdb and msdb).
When I do:
SELECT name as 'DatabaseName', HAS_PERMS_BY_NAME(name, 'DATABASE', 'CREATE BACKUP') as 'HasAccess' FROM sys.databases
It results in NULL for each database.
When I do:
SELECT IS_ROLEMEMBER ( 'db_backupoperator')
I get 0 because I probably don't have permissions to view the permission tables even though I know the user has that role assigned.
Any other way?
Your HAS_PERMS_BY_NAME() approach works for me, but I needed to change the permission name to BACKUP DATABASE. I got the name of the permission from the documentation for database-level GRANTs. Note, there's also a BACKUP LOG permission if you need to check that as well.
TL;DR -
SELECT name as 'DatabaseName',
HAS_PERMS_BY_NAME(name, 'DATABASE', 'BACKUP DATABASE') as 'HasAccess'
FROM sys.databases;
As for the IS_ROLEMEMBER() approach, that works for me unchanged. I see in the comments that you had a misrecollection about the name of the actual role. Is it possible that that's an explanation for the behavior that you were seeing?
All that said, I'd personally prefer the HAS_PERMS_BY_NAME() approach. Regardless of how the permission was granted, that will expose whether or not the current user/login has it.
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
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'
When I create a user in a database it is not showing in 'sysusers' table of the database until the user is granted with any database level privilege , how to identify a user with no privileges in a current database?
The sysusers system catalog table only shows who holds database-level access privileges.
If you want to check users that have been granted a role but don't hold database-level access privileges you can cross the sysroleauth with the sysusers system catalog table:
SELECT grantee
FROM sysroleauth
MINUS
SELECT username
FROM sysusers;
When granting a role to a user, or to another role, it will not validate if this exists.
It will only give a error if you attempt to grant a role to yourself, unless you have DBSECADM, or if you include the WITH GRANT OPTION keywords in a GRANT statement that assigns a role to another role.
For the follow up question:
is it legitimate to grant privilege to the user who is not granted any db level privileges?
Yes, it's legitimate. If you create a role and assigned it has the default to a user that does not have a db level privilege it will be granted an implicit connection to the database.
And in this case the user will only show up on sysusers after you issue the GRANT DEFAULT ROLE statement.
Other cases:
If a user is created using the CREATE USER statement you must look into the sysuser database.
If you mean creating objects on behalf of others schemas that don't have a user on the database you need to get all those owners.
You can find the system catalogs tables that store owners by querying:
SELECT UNIQUE t.tabname
FROM systables t
INNER JOIN syscolumns c ON (t.tabid = c.tabid)
WHERE c.colname = 'owner' AND t.tabid < 100
ORDER BY 1;
But probably you want to take only a look into systables, sysobjstate and sysprocedures.
Try the following:
SELECT owner
FROM systables
WHERE tabid > 99
UNION
SELECT owner
FROM sysobjstate
UNION
SELECT owner
FROM sysprocedures
MINUS
SELECT username
FROM sysusers;
Bear in mind that some internal users, like sqlj, sysibm and sysproc, can appear because the sysprocedures is not filtering internal ones.
If you want to see all the OS users that don't have database-level access privileges you can, in UNIX, do:
CREATE TEMP TABLE os_users(
username CHAR(32),
password CHAR(1),
uid INT,
gid INT,
gecos CHAR(256),
home_dir CHAR(256),
shell CHAR(32)
) WITH NO LOG;
LOAD FROM '/etc/passwd' DELIMITER ':'
INSERT INTO os_users;
SELECT username
FROM os_users
MINUS
SELECT username
FROM sysusers;
You can filter the OS users by the uid, normally 0 is the root user and the range [1-99] is reserved for special system users
Then some system begin UIDs for non-privileged users at 100. Others, such as Red Hat, begin them at 500, and still others, such Debian, start them at 1000.
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).
I am new to databases. Here I have logged in the user account:System
I then create a new user raj using the following command
create user raj identified by raj
Then I connected to the user raj using following command
grant connect to raj
Here I am granting privileges on the table client_master to raj
grant all on client_master to raj
Now I want to select the contents of table client_master
select * from raj.client_master
but it is giving an error that such table does not exist.
A quick search on google and you would find out that the select right is as simple as select.
grant select on client_master to raj;
However, it is not the real problem as when executing this command grant all on client_master to raj the select privilege is already included.
So here are the possibilities why you get this error :
The table does not exist (you need to create it).
It is in another schema, and you did not specify it.
You made a typo when writing client_master.
My guess is that you created the table in sys schema (which is really a bad idea btw) so the problem is the option 2 in the one I listed.
Try
select * from sys.client_master;
Note that if you don't want to always specify the prefix, you can create a synonym.
create synonym raj.client_master for sys.client_master;
Then
select * from client_master;
Would work.
Try running below command -
GRANT EXECUTE ON Find_Value TO smith;
This may help you to resolve your issue.