I'm working with a database (let's call it DB_data) that contains all of the tables for a series of applications. In an attempt to minimize downtime during upgrades, a facade database (let's call it DB_facade) has been created which has a view for each of the tables in DB_data. It also contains all of the functions and stored procedures, which work against these views.
In trying to lock down security in DB_data we've done a DENY on all of the tables for all of the users in DB_data. All of these users have also been created in DB_facade with permissions to the views.
The problem here, is that because of cross-database ownership chaining the DENYs in DB_data are overriding the GRANTs in DB_facade.
I'd like to avoid turning on ownership chaining for both of these databases because of the potential security issues (although in my original tests, that did seem to correct the access problem). Also, we're trying to minimize impact to the applications, so requiring all access to be through stored procedures and using certificates (for example) wouldn't work.
Does anyone have any other suggestions on how to handle this?
Thanks!
Do you have this problem if you exclude the DENY on the tables in DB_data? If you don't explicitly GRANT permissions on these tables, you may be able to get the security you need and get the access rights through the views.
from what i've seen and done, sql server doesn't let you have any permissions unless explicitly told so. You should be able to grant select (or use the role datareader) in DB_Data to the users, and as long as it's the same account and it's mapped to both databases (you'll have to grant select and exec on db_facade) that should work just fine.
You can create a view in the DB_data database for each view in the DB_facade database. The new views would have rights to select from the tables. GRANT SELECT on the views in DB_data. Change the views on DB_facade to SELECT from the views on DB_data. And, the tables would have DENY set.
I recognize one disadvantage to this; the users can still interact with the DB_data database. They wouldn't be able to access the tables, but they could access the new views.
Related
I'm curious if there is a way for a user to use a view in database A (they have permission to database A) that accesses tables in database B (and/or additional databases they don't have permission to) without the user having access to database B?
My scenario:
We currently have a database (database A) where most of the views are housed. Most users across the team also have access to database A. We are wanting to split out our data tables from database A into their own databases (on the same server). When we do this, of course, the views will break because the tables they access will now be in database B. Since there are so many views, I'm looking for an easier way. My thought was to use database A as the hub for the views and as the views are accessed, permissions are granted to the various databases for the user(s) - without giving them direct access to the other databases.
Thank you in advance.
I think a database role would be better than a database as the container for view access.
It might be easier to delete objects than to move them. A backup-restore can create a copy of the database. Then delete the tables and views that don't belong in each database.
Cutting corners on security or integration can come back to bite. If the tables are distinctly part of different systems, then the views should go with the tables. Security and integration between systems by cross database references will tie all those systems to the same server. (Linked servers would be a performance and DTC nightmare.) We have several "separate" justice applications (e.g., DA, Public Defender, Probation, etc.) that do this. Security is still detailed via the use of database roles for each use. The integration is great, but it's a nightmare to migrate because it's all at once and together. If done correctly (e.g., connections strings to each database), we would be able to move one database at a time and update and test one system at a time. As it is now, it takes a lot of project management and a long time to get everybody ready.
If the tables are part of the same system, then schemas could be an option to segregate them if database roles are to tedious to manage. Is it more work to segregate the objects into databases or schemas than to manage a role?
Also, if you use SSDT db projects, then those cross database references (circular?) can be a pain.
For security, I would suggest a database role for each group that needs access. There is no "magic" database level container just for views. The best you can do is SELECT which includes tables and views. For just views, a script is not hard to create to grant a db role select access to all views in the db. I would not ever use grant select and then a DENY on tables because it can prevent access to table for users that should have access. If one or more schemas are used for the views, a role can be granted SELECT access to the schema. This might be the best option. If the view schema and the objects accessed by the view have the same owner, the ownership chain should allow access via the view to tables. For example, if the "view" schema is owned by "dbo", views in the "view" schema should be able to access tables in the "dbo" schema without the user being granted access to those tables. (I have not tried it.)
It would be nice if there was a second flavor of INSERT, UPDATE, etc. permissions that applied to views only, but there isn't.
I am new to SQL Server database and I am struggling to figure out the access issue for one of the user on a particular view. I don't want to expose any of my base tables.
The scenario is: I have 3 databases, DB one, two and three
Database one has 2 base tables
Database two has one view on top of those tables (tables in database one)
Database three has one view which is on top of the view of database two
Database three is our data warehouse. So, I would like to know if I give select permission on only database three's view, will that suffice?
The catch is I don't want to expose any of my base tables in database one
If I grant select permission to user1 on datawarehouse view (view in database three) and deny all the permissions to the base tables (in database 1), then is it possible?
Thanks
Ownership chaining allows access to data via the view without permissions on the underlying tables as long as all objects are owned by the same security principal. There is no need for an explicit GRANT or DENY on the indirectly used objects with an unbroken ownership chain since permissions are checked only on the directly access view. The object owner is typically inherited from the schema owner.
To allow ownership chaining to extend across multiple database:
The DB_CHAINING database option must be ON for the databases involved.
The user must be able to use the databases (have a user account in each database with CONNECT permissions), although only permissions on directly accessed objects are needed.
In the case of dbo-owned objects, the databases must be owned by the same login (AUTHORIZATION) since the dbo schema owner is the database owner. For other schemas, the schema owner must map to the same login.
DB_CHAINING should be enabled only when you fully trust highly-privileged users (those with permissions to create database objects).
I want to grant read permissions for a user for a view which joins 2 tables from another database.
I don't want to:
give him permission on the database where the tables are or add him as an user there.
Make him the owner of the view/schema due to the security exploits.
I don't want to create first a table, or variations of a hack table with a truncate and a stored procedure which inserts the data on a trigger.
Can this be done somehow? Maybe there's something I missed and you guys might know.
I have read these posts but they didn't solve my problem:
Grant SELECT permission on a view, but not on underlying objects
Grant Select on a view not base table when base table is in a different database
https://msdn.microsoft.com/en-us/library/ms188676.aspx
https://dba.stackexchange.com/questions/89632/sql-server-grant-select-access-to-a-user-in-a-view-and-not-in-its-tables
Thank you
Edit:
The easiest solution I came up with, after some research, is activating the cross database ownership chainingoption on the database where I'm placing the views and granting the read permission to the users. This might be in contrast with my 2nd point of things I'm trying to avoid. Is this a good idea?
Give them a login to another database on the same server, and include only your single view, with the view pointing to your secure database. Don't give that login any access to anything but the database with the view in it, and only read access to that single view. Obviously, you'll have to fully qualify your table name (e.g., from SourceDB.dbo.SomeSecretTable).
What I ended up doing:
Create an active directory group.
Add users to the AD group.
Create a login for the AD group mapped for the source DB and target DB.
Add the user on the target DB and give him permissions only for the requested views.
(Optional) Added the group on all the databases to deny select.
Couldn't find a solution for my original question without the AD group.
I am using SQL Server 2008R2 and one of the things I am trying to do is allow users read-only access to some of the tables in one of the DBs via MS Access ODBC so that they cna build their own reports, etc (Their request). The problem is that they can see all of the system views /tables (information_schema and merge replication stuff). Is there anyway that I can revoke these so that all they can see are the tables /views I designate as available for selection?
Not sure what I can do to limit what they see as "available".
Thanks,
S
Put them on the public role, and only give SELECT permission to the tables/views you want.
You can't stop them from seeing the system views but you can stop them viewing what those views return. If they don't have permission on the table, sys.tables will not return that table.
In Oracle,
- I want to ensure that owner of trigger must match table owner.
- Also the views should be restricted. The user must not be able to query system views and tables.
Generally only the owner of a table will have privileges to create triggers on it. DBAs may have the privilege CREATE ANY TRIGGER, but protecting a database from a DBA is whole different order of question.
There are a number of system views (eg USER_TABLES, ALL_USERS) which you can't revoke access on, but they will only reveal what the user has been granted access to. Again the DBA will have access to views prefixed DBA_ and 'views' prefixed V$ (which are a bit odd in that they show operational information about the database and not data that is stored on disk anywhere) and tables owned by SYS.
What exactly is it that you want to accomplish?
Normally, we create roles that give access to only the application tables and views.
The owner of the application grants privileges to those roles and
the roles are granted to your users.
As long as the owner of the tables only has the regular 'create xxx' privileges, there is not much to worry for. Normally we need access to some system tables and views.
What data do you want to hide? Most of the views don't reveal more than already is known by the application.
Don't give 'xxxx ANY' privileges to anyone. Most of the time when those privs are requested it is because of laziness. They are rarely needed.
Ronald.