SQL Server - What role to use for application access? - sql-server

What Server Role(s) and/or Database Role(s) must a SQL Login have to do the following:
Read Data (including Temp tables)
Write Data (including Temp tables)
Execute any SP within a database which they are granted access
We are migrating from SQL 2000 to 2008 and I'm going through all the Logins and have noticed they are all set to sysadmin & db_owner, which isn't good. Our apps that use these logins will only do what I've listed above so that's why I'm wondering. I know I can set each Login with a Database Role of db_datareader & db_datawriter but that doesn't include executing SP's. We've got close to 300 SP's in 2 or our DB's and to have to go through each SP and set the login permissions in the Extended Properties would be WAY too long and tedious.
Any help is greatly appreciated!

to have to go through each SP and set the login permissions in the Extended Properties would be WAY too long and tedious
And yet, this would also be the most secure.
Using the built in roles exposes too much of your database to your application.

Can you give the db_datareader and/or db_datawriter execute rights? This will give the user rights to execute any stored procedures in databases it has access to. If you have views you will also need to grant them select rights.
GRANT EXECUTE TO db_datawriter

I would either just deal with it and set the permissions manually or (my preference) create database roles that have the types of permissions you want to give, and assign logins to those. That way if multiple logins need the same set of permissions, you just give them the same role.
As a bonus, if your programmability objects have some sort of prefix naming convention so that (for example) procedures that read from your login information tables all start with something like pAccount_ or something, then you can dynamically do GRANTs to roles based on the prefix of the routine.

Related

SQL Server roles and permissions

I really need some advice about adding roles at the server level and apply some permissions that will be applicable to each database on my server.
Basically I need to two roles read only and read write.
The read will have permissions to select and see any object
The write will have permissions to select/insert/delete and execute any object
I want to create a server role, then a login associated to this role (which can be a AD group) and after that for each database create a user that will inherits all permissions from the server role.
So on each database, I will have each user that belongs to the server role created, the problem is to clearly define the permissions, is not straight forward in my opinion.
What I can see, I cannot assign read or write to a role and then use it on each db, on the contrary on the General tab of the server role I have a bunch of permissions that is not clear which one to use for this purpose.
Maybe I'm doing it wrong but I want to have something at the server level and not define the same role on each db for that purpose. I'm using SQL server 2014.
The short answer is you can't.
Generally, server-level permissions are not propagated down to individual objects within databases. The only exception is a sysadmin role, which I would strongly encourage you not to use for this purpose, as you would essentially give up the control of the entire server instance to every member of it.
As a kind of a shorthand, you can use built-in database roles to save yourself a bit of trouble. For read-only access, a membership in db_datareader role is usually enough, unless you have stored procedures that return datasets which this role is supposed to be able to execute. There is also a similar role for modification, db_datawriter, but it doesn't cover the execute permission. So you will have to create a custom role for that:
create role [DataChanger] authorization [dbo];
go
alter role [db_datareader] add member [DataChanger];
go
alter role [db_datawriter] add member [DataChanger];
go
grant execute to [DataChanger];
go
-- Now you can add your members. Here is a reader
create user [Domain\MyUser1] from login [Domain\MyUser1];
go
alter role [db_datareader] add member [Domain\MyUser1];
go
-- Writer
create user [Domain\MyUser2] from login [Domain\MyUser2];
go
alter role [DataChanger] add member [Domain\MyUser2];
go
These permissions will automatically pick up newly created objects, without you having to explicitly add new permissions after every schema modification.
You will have to do this in the context of every user database that you want to manage in this way. You can probably create a SQL Agent job which will run periodically and introduce these changes in any user databases which don't have them already (for example, if a database has been restored from earlier backup, or brought from another server, or a new one was created). Also, since you can't loop through databases in static code, you will need to wrap it into a dynamic SQL and loop through sys.databases, or maybe via an undocumented sp_MSforeachdb system stored procedure. Oh, and don't forget to remove all these go statements from dynamic code, as they are not part of SQL, and are only recognised by SSMS and sqlcmd.
P.S. All that being said, I hope you are not going to manage any production databases in this manner. I don't even know where to start on how insecure this approach is.

SQL Server Find Least Privilege for user account

I have a vendor who has installed an application database on one of my SQL Server 2012 instances. He has told me that the SQL Auth account used by the application requires DB Data reader, Data writer, DB owner, and sysadmin. This makes no sense to me because sysadmin would not need the other roles. After install I removed sysadmin and the account had data reader and writer. The application stopped working.
So I am looking for some tips and ideas for figuring out the least privilege required for the application user. I see that the database has stored procedures but there aren't any functions, types, assemblies so I would like to just create a role with all of the required grants. DB Owner would be better than sysadmin. I could live with that.
It depends on what the application needs to do. If your application was only reading data, then the datareader role. If it reads and writes to the database, both reader and writer would be good. Note that writing data only includes inserting and updating, not modifying or altering. In most cases, you can assign a series of roles and not provide the login access to commands such as truncating or dropping tables - it's obvious why an application having god powers would be a bad idea.
Here's a list of all the possible roles you can assign and what each of them is for. Hopefully understanding what the application does will help you assign these roles more fluidly.
Predefined database roles
You may need to create your own, but you have access to several predefined database roles:
db_owner: Members have full access.
db_accessadmin: Members can manage Windows groups and SQL Server logins.
db_datareader: Members can read all data.
db_datawriter: Members can add, delete, or modify data in the tables.
db_ddladmin: Members can run dynamic-link library (DLL) statements.
db_securityadmin: Members can modify role membership and manage permissions.
db_bckupoperator: Members can back up the database.
db_denydatareader: Members can’t view data within the database.
db_denydatawriter: Members can’t change or delete data in tables or views.
Fixed roles
The fixed server roles are applied serverwide, and there are several predefined server roles:
SysAdmin: Any member can perform any action on the server.
ServerAdmin: Any member can set configuration options on the server.
SetupAdmin: Any member can manage linked servers and SQL Server startup options and tasks.
Security Admin: Any member can manage server security.
ProcessAdmin: Any member can kill processes running on SQL Server.
DbCreator: Any member can create, alter, drop, and restore databases.
DiskAdmin: Any member can manage SQL Server disk files.
BulkAdmin: Any member can run the bulk insert command.
You can create a database role to be able to execute stored procedures. It'll even show up in the UI when you grant permissions to a login for a specific database:
-- Create a db_executor role
CREATE ROLE db_executor
-- Grant execute rights to the new role
GRANT EXECUTE TO db_executor

Setting up a user to my database in my SQL Server

I just finished creating a new user for my database in SQL Server. I had 4 tables I wanted to grant Insert, Update, Select and delete permissions. I did this manually in the Securables area of the new user.
Is there a better way to do this that to have to touch each object? if so, how?
Thanks,
rod.
One way is use schemas such that
tables belong to a schema (let's call it data, CREATE SCHEMA)
users belong to a role (CREATE ROLE, sp_addrolemember)
permissions are assigned to the role on the schema (GRANT INSERT ON schema::data to myRole)
Now, you can add new tables or change users without losing/creating permissions
If you want finely granular control over who can do what, I don't think there's a whole lot you can do - you're doing it just fine.
gbn's approach is quite nifty - another approach for "simple" setups (when you don't need a whole lot of different permissions) is to:
grant every user (or a role) the database role db_datareader - this allows read access
(SELECT) on all tables and views
grant every user (or a role) the database role db_datawriter - this allows write access (INSERT, UPDATE, DELETE) on all tables and views
If you also need to grant execution rights on stored procedures, there's unfortunately no predefined role to use. You can however create your own database role and then grant execute permissions to that role. The great thing is: this permission to execute stored procedures also applies to all future stored procedure you might create in your database!
To define your new role, use this:
CREATE ROLE db_executor
GRANT EXECUTE TO [db_executor]
and then you can just assign db_executor to those users who need to be able to execute stored procs and stored functions in your database.

Lock out non-dbo

Is there an easy way to lock a sql server express 2005 so that only DBOs can get to it, assuming you have a system where everyone has been granted rights individually and you can't just disable a role?
ALTER DATABASE <dbname> SET RESTRICTED_USER
and to set operation back to normal:
ALTER DATABASE <dbname> SET MULTI_USER
You can remove all other access than dbo from the database, then only the dbo's will be able to use it.
However, members of the sysadmin group are by default dbo's, I am not sure if you can block access for these users.
Is there not a server wide setting for DBO-Only? I do not have an example close to hand, but from my Sybase days I seem to remember such a setting.
Restricted user mode should do it. Granted it will also let in dbcreator and sysadmin, but that only makes sense. So ensure your accounts don't have one of those roles either or they will be able to get in when in Restricted User Mode.
http://technet.microsoft.com/en-us/library/ms188124.aspx
Restrict Access
Specify which users may access the database. Possible values are:
* Multiple
The normal state for a production database, allows multiple users to access the database at once.
* Single
Used for maintenance actions, only one user is allowed to access the database at once.
* Restricted
Only members of the db_owner, dbcreator, or sysadmin roles can use the database.

How to disable SQL Server Management Studio for a user

Is there a way to prevent users from getting into SQL Server Management Studio so that they can't just edit table rows manually? They still need to access the tables by running my application.
You can use the DENY VIEW ANY DATABASE command for the particular user(s). This is a new feature available in SQL Server 2008.
It prevents the user from seeing the system catalog (sys.databases, sys.sysdatabases, etc.) and therefore makes the DB invisible to them in SQL Management Studio (SSMS).
Run this command from the Master Database:
DENY VIEW ANY DATABASE TO 'loginName'
The user is still able to access the database through your application. However, if they log in through SSMS, your database will not show up in the list of databases and if they open a query window, your database will not appear in the dropdown.
However, this is not fool-proof. If the user is smart enough to run the Query Command:
USE <YourDatabaseName>
Then they will see the database in the Query Analyzer.
Since this solution is taking you 90% there, I would give the database some obscure name not let the users know the name of the database.
You DO NOT need to worry about them having access to the tool. Simply make sure they do not know any of the SQL logins for the specific Databases that have read/write permissions, if they do, change the password. If they have access to the DB via Windows Authentication, make sure that they are in a datareader role. You can use roles to manage what the users can do in SQL.
You can use a trigger.
CREATE TRIGGER [TR_LOGON_APP]
ON ALL SERVER
FOR LOGON
AS
BEGIN
DECLARE #program_name nvarchar(128)
DECLARE #host_name nvarchar(128)
SELECT #program_name = program_name,
#host_name = host_name
FROM sys.dm_exec_sessions AS c
WHERE c.session_id = ##spid
IF ORIGINAL_LOGIN() IN('YOUR_APP_LOGIN_NAME')
AND #program_name LIKE '%Management%Studio%'
BEGIN
RAISERROR('This login is for application use only.',16,1)
ROLLBACK;
END
END;
https://www.sqlservercentral.com/Forums/1236514/How-to-prevent-user-login-to-SQL-Management-Studio-#bm1236562
I would suggest you lock down the database and give appropriate read-only (or other) rights to the user. That way the user can still use management studio to run select queries and such.
If you don't want the user to have any rights at all then you could do that as well.
If your application is running as a service/user account then only that account requires access to the database. The individual users' account do not require any access to the database and therefore they won't even have read access. Your app will be the gateway to the data.
If the users are running the application under their user accounts then grant them read-only permission. You can simply add them to the db_datareader role.
Hope this helps!
You can deny 'Users' access rights to the ssms.exe executable file, while granting the relevant users/administrators rights to it.
If your application only used stored procedures to modify the data, you could give the end users access to run the stored procs, but deny them access to modify the tables.
Don't let them know what the database login is.
If you can't restrict the login, use stored procedures exclusively for updates and disable any CREATE,DELETE,INSERT, or UPDATE permissions for that user.
An Application Role will allow you to secure database objects to your application instead of the logged on user.
I agree with Jon Erickson as a general rule
do not allow any users access to the tables, but only allow access through stored procs
do not allow general user accounts access to stored procs, but only the account your app runs under (whether it's an integrated login or SQL login)
Make well usage of Database Roles, if Users should only have SELECT (read) access assign them the db_datareader Role. Even if they login using SSMS they will can execute only SELECT statements.

Resources