SQL Server View permissions need table permission too - sql

We've built a collection of views, under a specific schema as we wanted to set the SELECT permission only to some developers for that particular schema, and perform the same logic for other developers working on data from other schemas.
The challenge we're facing now is that, e.g., View_X, under schema Schema_X (owner = dbo), selects data from Table_X under Schema_Y (owner = dbo).
The setup at the moment is built this way:
We created Role A with Developer_A and Developer_B as members;
For which we've DENIED all permissions for securable SCHEMA Schema_Y and other schemas, as we only want these members to select data from Schema_X. When Developer_A or Developer_B
query View_X, they get the error saying they don't have permissions for Schema_Y
Is there a way to prevent our developers to query Table_X or other tables from Schema_Y, via SQL Server permissions? Or any other way via some other user management logic?

There's something else going on. A DENY won't prevent ownership chains; ownership chains suppress permissions checking entirely. eg
create schema X
go
create schema Y
go
create table Y.tt(id int)
go
create view X.vtt as select * from Y.tt
go
create user xv without login
grant select on schema::X to xv
deny select on schema::Y to xv
go
execute as user='xv'
select * from X.vtt
revert

Related

Why is CREATE table missing from DDL export script in SQL Developer?

I'm trying to retrieve the CREATE table statement for multiple tables from oracle SQL Developer so I can run it in SQL Management to create new tables.
However, when highlighting multiple tables and right clicking > Quick DLL> Save to File, my file looks like this:
GRANT INSERT ON "OPSR"."BOOTH" TO "OPSWEB";
GRANT UPDATE ON "OPSR"."BOOTH" TO "OPSWEB";
GRANT SELECT ON "OPSR"."BOOTH" TO "OPSWEB";
GRANT DELETE ON "OPSR"."CAAR_BOOTH" TO "OPSWEB";
GRANT INSERT ON "OPSR"."CAAR_BOOTH" TO "OPSWEB";
GRANT SELECT ON "OPSR"."CAAR_BOOTH" TO "OPSWEB";
GRANT UPDATE ON "OPSR"."CAAR_BOOTH" TO "OPSWEB";
Why is there no CREATE table statements in here?
I'm connected as Opsweb and the only tables I can see are under the OPSR user.
You can't see the create DDL for other user's objects. SQL Developer is using dbms_metadata in the background, and from the documentation:
The object views of the Oracle metadata model implement security as follows:
Nonprivileged users can see the metadata of only their own objects.
Nonprivileged users can also retrieve public synonyms, system privileges granted to them, and object privileges granted to them or by them to others. This also includes privileges granted to PUBLIC.
If callers request objects they are not privileged to retrieve, no exception is raised; the object is simply not retrieved.
If nonprivileged users are granted some form of access to an object in someone else's schema, they will be able to retrieve the grant specification through the Metadata API, but not the object's actual metadata.
and so on. As the last bullet above says, you cen get the grants - which is what you are seeing now - but not the actual metadata.
If your user was granted the select_catalog_role you would be able to get the DDL for OPSR's objects, but you'd have to ask your DBA for that and it would probably be easier to connect as that user, or ask someone else who can to do that to perform the extract for you.

Checking if a user has the required permission in snowflake to create and write into a table

I was using node.js to work on snowflake datawarehouse as a destination for users. I wanted to check if a user has the required permission level on the schema to create a table and write into it before adding the user to the database otherwise it should give an error saying that the user does not have the appropriate permission level. How can I achieve that programatically?
Thanks,
one way you could do is check if the role has SEELCT privilege on the table by looking into the view TABLE_PRIVILEGES in information_schema schema.
select * from information_schema.TABLE_PRIVILEGES where table_name = 'SALES_RAW'
Due to how permissions can be inherited through the role hierarchy, this isn't easy to do. Permissions aren't assigned to users in Snowflake, they are assigned to roles. You could use the table_privileges in the information schema (as Himanshu said). You'll need to ask your admin for privileges to the information_schema schema in the databsae:
You could probably use some combination of these too:
show grants to user [username]
with
show grants on schema [schema name]
The easiest way would be to have your app / script / service assume the same role as the user and see if you can select from a table in the schema or try to create a temporary table in the schema. If you receive an error code, the user doesn't have permissions!

Create a SQL Server view with different permissions

I have created a view in Database A that looks at tables in Database B that the users in Database A do not have access to (HR Data).
Is there a way I can grant anybody calling the view in Database A permissions to see the results, without giving access to the underlying tables?
Both databases are on the same instance, SQL Server 2019
You can just
GRANT SELECT ON OBJECT::[schema].[theView] TO User1,User2
in your Database A? This way you'd just give SELECT permissions to the view itself, and not the tables.
If you have a lot of cases like this, you can also consider creating a special schema for this and do:
GRANT select ON Schema :: [DBO] TO User1
instead.

Giving permissions on SQL database

I am in the process of configuring database users for some new developers and I am running into some difficulties as I am reading lots of articles and it's not working out too well for me. I have tried various configurations manually and with T-SQL but I need a more efficient method.
My objective:
Some TSQL I can launch to give a database user the following permissions:
Grant permission to execute all Stored Procedures within the Database
Deny permission to View Definition of all of these stored procedures
Grant permission to SELECT, UPDATE, INSERT, DELETE from all tables within the database
Deny permission to View Definition of all of the tables in the database (I don't want them to view the data)
What I have tried:
I have achieved this manually but I have 200+ stored procedures and 100+ tables so I don't want to do it manually. From the T-SQL aspect I have managed to get the following to work:
USE database_name;
GRANT EXECUTE TO [security_account];
This works and allows the users to run the stored procedures but they cannot view the actual query code. I need the same logic for the tables as described above.
Thank you for your help.
I am not quite sure if this is a viable solution to your problem. But maybe it will get you at least closer to what you want. So, here is the setup I'd propose:
Do not grant anybody any permissions on any table.
Use stored procedures for DML.
Grant execute on all these stored procedures to public.
Setup one table in your database which lists all users which have access to your database including their login (suser_sname()) and their permissions (for example MayAlterTableUsers).
Implement into all stored procedures a check similar to this
if (
select isnull(MayAlterTableUsers, 0)
from tblUsers
where LoginName = suser_sname()
) > 0
begin
select N'Implementing the requested changes to tblUsers.'
end
else
begin
select N'You don''t have the required permission.'
end
Setup you views similar and grant select on all views to public
create view vShowAllUsers as
select *
from dbo.tblUsers
cross apply (
select MaySeeAllUsers
from dbo.tblUsers
where LoginName = suser_sname()
) as p
where p.MaySeeAllUsers = 1
In the end all views and all stored procedures will be publicly available but the handling of permission will be within each one of them. All permissions themselves will be within this table tblUsers. Since nobody has the possibility to alter this table tblUsers unless (of course) they are in this table with the appropriate permission, this DB setup is self-contained.

User/Role can Create table or view, but not select from it SQL Server 2008 - Ownership not passing to creator

I'm trying to create a role to give a few users permission to create and alter views, procedures and tables.
I don't want these users to be able to select from/update/delete/alter etc. any table in the database, there are tables we want to keep control of - but they should have full permissions on any objects they create.
I've given the users permissions to create views etc. and that works fine, but they can't then select from views they then create. Is it possible to do this?
-- ADDED 25/july/2013
Example:
An example user Mike has specific permissions granted on a handful of tables. All Grant, no Deny.
No other database level permissions beyond "connect"
Plus is a member of public (not altered - no denys), plus 3 other roles we have set up
Role: Standard_Reader
Specific Select permissions on a number of tables. All Grant, no Deny.
No other database level permissions
Role: SensitiveDemographicsReader
Specific Select permissions on sensitive tables. All Grant, no Deny
Role: Analyst
No Specific securables
Database level permissions:
Create Function
Create Procedure
Create Table
Create View
This user can create a table or view, but once created, can't select from it.
Is it possible to set up SQL server so that whenever a user user creates a table or view they then have permissions to select from it (assuming they have permissions on underlying tables in view)
-- EDIT
After some investigation it has become apparent that for some reason in our database, ownership of objects is not acruing to their creators.
Found using this code
select so.name, su.name, so.crdate from sysobjects so join sysusers su on so.uid = su.uid
order by so.crdate
All owners, with a couple of exceptions are DBO.
I can't understand why ownership is not passing to the creators of objects. Any idea what could cause this?
Sounds like what you're using to deny them in the first place is overriding the default settings. Can you post more information on what permissions the users have?
Can't comment :(
I would comment but lack privileges; have you taken a look at MySQL table permissions? It's a rather good system.
you need to grant SELECT on the schema to user/group:
GRANT SELECT ON SCHEMA::dbo TO User/Group;