Best way to restrict access to different schemas in a single database - sql

In SQL Server, I want to create a database with multiple Schemas each of which relevant to a specific Domain of my application.
I would also like to create a restricted access to each schema meaning that when a user logs in to the database (either from ssms or from entityframework inside application) he/she can only access to objects in the database with the one specific schema he/she has access to and also can do all ddl/dml commands with that schema.
I have came up with the following solution:
1- Create a database login
CREATE LOGIN [AccountingDataBaseLogin] WITH PASSWORD='AccountingDataBaseLoginPassword'
2- Create a database user for the created login in step 1.
CREATE USER [AccountingDataBaseUser] FOR LOGIN [AccountingDataBaseLogin]
3- Create a Schema:
BEGIN
EXECUTE('CREATE SCHEMA Accounting AUTHORIZATION AccountingDataBaseUser')
ALTER USER AccountingDataBaseUser WITH DEFAULT_SCHEMA = Accounting
ALTER AUTHORIZATION ON SCHEMA::Accounting TO AccountingDataBaseUser;
GRANT CREATE TABLE TO AccountingDataBaseUser;
GRANT CREATE VIEW TO AccountingDataBaseUser;
GRANT CREATE PROCEDURE TO AccountingDataBaseUser;
GRANT CREATE TYPE TO AccountingDataBaseUser;
GRANT CREATE FUNCTION TO AccountingDataBaseUser;
GRANT CREATE DEFAULT TO AccountingDataBaseUser;
END
In my application I create a seperate .edmx file for each Schema and I will have to have a distinct connection string for each .edmx as follows:
<add name="AccountingDataBaseEntities" connectionString="metadata=res://*/ModelDesigners.Accounting.AccountingDataBaseModel.csdl|res://*/ModelDesigners.Accounting.AccountingDataBaseModel.ssdl|res://*/ModelDesigners.Accounting.AccountingDataBaseModel.msl;provider=System.Data.SqlClient;provider connection string="data source=.;initial catalog=APADataBase;user id=AccountingDataBaseLogin;password=AccountingDataBaseLoginPassword;MultipleActiveResultSets=True;App=EntityFramework"" providerName="System.Data.EntityClient" />
I would like to know if what I am doing is the best way to achieve what I want and if not what would be a better way?

You can grant permissions to the schema directly:
GRANT SELECT, INSERT, UPDATE, DELETE ON SCHEMA::Accounting TO AccountingDataBaseUser;
If you have more than one users need to access the same schema, you can create a database role and GRANT the above permissions to the role. Then add the users to the role.

That is a reasonable implementation of your objective. In particular, you didn't make the common mistake of having the schema owned by dbo and allowing other users to create objects in it.
A couple of possible improvements to your model are
1) Have a role own the schema instead of a user
2) Have one role for the schema owner, and another one without DDL privileges for the application

Related

Grant from schema A of Schema B tables to schema C

I have an application schema U32_C5 and another schema MIG_SRC which has some tables and then we have a ROLE RO_ROLE on which we have some grants of tables from Schema U32_C5.
The RO_ROLE is assigned to another Schema MRGO_RO which is Read Only.
Here I need to grant select on tables from MIG_SRC to MRGO_RO catch here is that the process which and from where I can include these grants is run from application schema U32_C5 in production so when I tried to to something like below it says table or view does not exists (which seems to be obvious)
execute Grant from U32_C5
grant select on MIG_SRC.MOBILE_CELLPHONE_PAIRINGS to MRGO_RO;
Another way which I think of is creating DB link on MRGO_RO for MIG_SRC Schema but it enables read/write operation as well on MIG_SRC tables which is not allowed on production.
DB Links is present on U32_C5 Schema for MIG_SRC Schema
So looking for a way to accomplish above task without creating DB Link any suggestion is welcome.
Sample Script of requirement what I want to achieve Please Remember I cannot and do not want Login to MIG_SRC and only way I am looking for is to do it by using U32_C5 and without DBA HELP
A RO ROLE Created by DBA's
Create role RO_ROLE;
/* Create application schema, table inside it and grant select on it to RO_ROLE*/
CREATE USER U32_C5 IDENTIFIED BY U32_C5 DEFAULT TABLESPACE;
GRANT ALTER SESSION TO U32_C5;
GRANT CREATE SESSION TO U32_C5;
GRANT CREATE database link TO U32_C5;
GRANT CREATE table TO U32_C5;
create table U32_C5_test_tab (id number);
grant select on U32_c5.U32_C5_Test_tab to RO_ROLE;
/* Create Read Only schema, grant RO_ROLE to it */
CREATE USER mrgo_ro IDENTIFIED BY mrgo_ro DEFAULT TABLESPACE;
GRANT ALTER SESSION TO mrgo_ro;
GRANT CREATE SESSION TO mrgo_ro;
grant ro_role to mrgo_ro;
/* Create SRC schema, table inside it */
CREATE USER MIG_SRC IDENTIFIED BY MIG_SRC DEFAULT TABLESPACE;
GRANT ALTER SESSION TO MIG_SRC;
GRANT CREATE SESSION TO MIG_SRC;
GRANT CREATE database link TO MIG_SRC;
GRANT CREATE table TO MIG_SRC;
create table mig_src_test_tab (id number);
/* login to Apllication Schema U32_C5 */
sqlplus U32_C5/U32_C5#SID
grant select on mig_src.mig_src_test_tab to mrgo_ro; -- for me it gives error here at this step table or does not exist
/* login to Read Only Schema mrgo_ro */
sqlplus mrgo_ro/mrgo_ro#SID
select * from mig_src.mig_src_test_tab;
or
select * from mig_src_test_tab;
If I understood you correctly, then WITH GRANT OPTION is what you're missing.
Once someone (A) grants privileges on their own objects to someone else (B), and that (B) has to "forward" those privileges to (C), then it is the WITH GRANT OPTION that helps.
Documentation says:
Specify WITH GRANT OPTION to enable the grantee to grant the object privileges to other users and roles.
Restriction on Granting WITH GRANT OPTION You can specify WITH GRANT OPTION only when granting to a user or to PUBLIC, not when granting to a role.
It means that you should grant privileges directly, not via role. That fact doesn't have to be a drawback because of named PL/SQL procedures, where privileges acquired via roles won't work anyway, so you might end up in direct grants anyway.
Other option - which you might consider - is related to what you said:
when I tried to to something like below it says table or view does not exists
If you created a synonym for those tables, then you wouldn't get such an error.
Database link isn't an option, as you said - by using it, you have full access (as you have to know username/password to create the DB link, and that isn't really read only access).

Redshift user with default access to newly created schemas

Is there a way for an AWS Redshift user to have select only access on newly created schemas created by a separate Redshift user?
For example, if I create a user as follows:
CREATE USER francesco_totti WITH PASSWORD xxxxxx;
GRANT USAGE ON SCHEMA "forza_roma" to francesco_totti;
GRANT SELECT on all TABLES in schema "forza_roma" to francesco_totti;
ALTER DEFAULT PRIVILEGES IN SCHEMA "forza_roma" GRANT SELECT ON TABLES TO francesco_totti;
How can I grant the francesco_totti user access to schemas that are created later on by a separate user? I want to alter the default privileges to allow francesco_totti to read from newly created schemas. Is this possible?
This is not possible as It's against the data security policy. We need to provide Authorization and access to each individual user or user group. What you can do is create a group and provide access

How can I restrict CREATE TABLE access for a user (who has ddladmin membership) to a specific schema (sql server)?

i have one user who have ddladmin membership i want to restrict him on creating table on dbo schema can i do that ?
or i have to go for user define role
You can use REVOKE for CREATE TABLE on the database to restrict that user from creating any tables.
Try the following sample:
REVOKE CREATE TABLE ON <DB_Name> FROM <UserName>
for Schema level, please try the following:
REVOKE CREATE TABLE ON SCHEMA::<schema_name> TO <UserName>

Prevent all users from accessing tables/views under a schema

I am connecting to my SQL studio manager using Power BI (a report writing software). I only want tables appearing listed under a certain schema, and deny permission to access all others, instead of displaying all tables which it currently does.
Usually, when preventing individual users from accessing a schema, I would use the following code:
revoke select on schema::UnwantedSchema to User
grant select on schema::WantedSchema To User
However, now I want it so ALL users and Logins have these permission settings. Not just the individual user. Is there a way I can do this without having to set the permissions for every individual user?
If you wanted to set the privileges to multiple user logins, You need to create a role and assign the role to the ers to that role. The give required permission to the role created.
Following are the sample steps.
--Create a new role
EXEC sp_addrole 'yourRole'
GO
--Assiging role to the user
EXEC sp_addrolemember 'yourRole', 'yourUser';
GO
--Assigning permissions to the Role
GRANT ALTER, DELETE, EXECUTE, INSERT, REFERENCES, SELECT,
UPDATE, VIEW DEFINITION ON SCHEMA::YourSchema TO yourRole;
GO
GRANT CREATE TABLE, CREATE PROCEDURE, CREATE FUNCTION, CREATE VIEW TO yourRole;
GO

Vertica role grant not working

I am trying to setup a new role for making the access rights granting easier. I was wondering if there is an easier way to give select on all tables (newly created tables should be accessible automatically) under a schema to selected users. I ran following queries for the same. But still my user is not able to access the specific table.
CREATE ROLE myrole;
GRANT SELECT ON myschema.mytable TO myrole;
GRANT usage ON schema myschema TO myrole;
CREATE USER mytest1 identified BY '***';
GRANT myrole TO mytest1;
After this, when I login with mytest1 user and trying to run select on myschema.mytable it is asking me to grant usage on schema to user. After I grant usage on schema to user directly it is failing with permission denied for that table.
Please help with the same. I am running on vertica 5.0
Update:
I find that u also have to make that role default or explicitely set that role as default for user session for making the role's effect take place.
ALTER USER mytest1 DEFAULT ROLE myrole;
But still, my another question of how to make all tables under a schema accessible to specific users remains.
As per the Vertica SQL Reference Manual.pdf (page 725) (doc version 5.0 - for page numbers)
GRANT (Schema)
...
USAGE
Allows the user access to the objects contained within the
schema. This allows the user to look up objects within the
schema. Note that the user must also be granted access to the
individual objects. See the GRANT TABLE (page 727) ... .
The the user must also be granted access to the individual objects means that you need to also GRANT table.
The two I use is GRANT SELECT and GRANT REFERENCES which allows the user to run queries and join (reference) tables in the query.
Example:
GRANT SELECT ON TABLE [schema].[Table1] TO myUser;
GRANT SELECT ON TABLE [schema].[Table2] TO myUser;
GRANT REFERENCES ON TABLE [schema].[Table1] TO myUser;
GRANT REFERENCES ON TABLE [schema].[Table2] TO myUser;
...
6.0 doc reference GRANT SCHEMA (page 808) and GRANT TABLE (page 813).