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.
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
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.
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).
Am working on Sybase ASE 15.5.
I have 2 databases created in the same server, "DatabaseA" and "DatabaseB". The database owner is "User".
Logging in as "User" I created a table in "DatabaseB", called "TableA".
Now, my user has access to both database, but the default database is "DatabaseA".
This is sucessful when i login to DatabaseA:
USE DatabaseB
GO
SELECT * from DatabaseB.User.TableA
GO
But this is not:
USE DatabaseA
GO
SELECT * from DatabaseB.User.TableA
GO
It tells me that there is "No such object or user exists in the database".
I have Googled and most sites say that if the user has rights, then you only need to append the database and owner name to the table to access it. But it does not seems to work for my case.
I have tried creating a non DBO user "User2", and assigning it select rights using
GRANT SELECT ON DatabaseB.User.TableA to User2
and sp_helprotect shows that the rights is there for this user. But the results are exactly the same as when i query it with User.
Below is the result from sp_helprotect
grantor | grantee | type | action | object | column | grantable
'User' | 'User2' | 'Grant' | 'Select' | 'TableA' | 'All' | 'FALSE'
Is there anything configuration or setting that needs to be checked to enable this?
EDIT (22 July 2015)
Just discovered something. There are a few tables with DatabaseB that i can access from DatabaseA, but not all tables.
For example, there is TableA, TableB, TableC, and TableD in DatabaseB. Out of which TableB and TableD can be queried from DatabaseA using
USE DatabaseA
GO
SELECT * from DatabaseB.User.TableB
GO
SELECT * from DatabaseB.User.TableD
GO
which is sucessful. And
USE DatabaseA
GO
SELECT * from DatabaseB.User.TableA
GO
SELECT * from DatabaseB.User.TableC
GO
fails.
Help!!!
try SELECT * from DatabaseB..TableA to fetch the result from different database
also you can do below
use DatabaseB
SELECT * from TableA
you must at least have read access to the database .
Just another example :
Just another example:
select tabA.*,tabC.* from DatabaseB..TableA tabA, DatabaseA..TableC tabC
where tabA.xxx = tabC.xxx
The ASE server login seems to be 'User' -- a login is the thing that needs a password. This is not the same as the database user inside a database. THis mapping is established with 'sp_adduser'.
To resolve your problem, you need to figure out which DB user you are.
Run the following:
use DatabaseA
go
select user_name() user_in_A, suser_name() login_name
go
use DatabaseB
go
select user_name() user_in_B, suser_name() login_name
go
The output of these queries should help you move forward.
Having a login and user caled "USER" is not a good idea as it is also the name of the system function that returns the name of the current user. Can you try the same query using a different user altogether (eg. "bob")?
You may need to grant the appropriate permissions to bob but at least there won't be any confusion about user names.
This is further to RobV's comments (I don't have enough rep to add comments though!)