SQL Auth user that can restore some (but not all) databases - sql-server

I'd like to setup an SQL Auth user in MS SQL 2005 that can restore some, but not all, databases in a particular instance.
I'm not sure if I should use Server Roles for this, since they would seem to apply to all databases, but Database Role membership doesn't seem right either (I don't want the SQL user to potentially 'lose' their restore ability if they restored a backup that didn't contain their database role membership).
How can I accomplish this?

You can't set up a user as such. This permissions sits above database/users at the server/login level
The login could have "dbcreator" which says:
...and can alter and restore their own
databases.
Even using GRANT would be tricky if not impossible, say, to "GRANT CREATE ANY DATABASE"
Restore is, in a way, a drop and create. Or simply a create.
I'd suggest the best solution (but probably not what you want to hear...) would be to create your own stored proc in master that checks rights and issue the RESTORE command if the login is set up as a user in that DB
Example: sp_checkandrestore 'dbname', 'backupfile'

Related

SQL Server 2008 - Put database user permissions back in after restore without sa privileges

What would be the best way to allow users to manage their own database restores from backup files? The reason I ask is because I have a user who is the db_owner for
a db. He loses access as soon as he restores the database from a backup file from another instance(of course because he does not have access on that instance), and
then someone with sa permissions has to restore his permissions. Is there anyway he can restore the backups, and then put back the db owner permission on the database that he already had?
Your best bet at this point is to create a custom stored procedure that does the following style pseudo code:
Take the database name, backup file name
Check to make sure the person requesting is the owner
Restore the database over the original
Set the owner back to the original in #2
Build in some logic to check and make sure people aren't trying to abuse it, give bad values, etc. Sign the procedure with a certificate and use a special account just for this purpose to lock down possible intruders/malicious people.

Copying SQL Server Express database to another server

I need to copy a SQL Server Express database from one one server to another (virtual) server.
I know how to do this for the database itself - with a backup and restore. I have also looked at this and this which show how to script this - that's great.
However, I also need the permissions to go with it but can't figure out how to do that.
Any pointers would be warmly welcomed.
The logins need to exist already on the destination server, but once they exist, you can wire-up the logins back to the users with a script like this:
sp_change_users_login 'Update_One', 'user-name', 'login-name'
More information on sp_change_users_login can be found on MSDN
Logins are at a server level. Users are at a per-database level. Generally I keep the login name and user name the same to avoid confusion, but they can be different. The Users define the permissions within the database and you've not lost them, just the link to the login.
As an alternative to sp_change_users_login
ALTER USER username WITH LOGIN = newlogin

SQL Server permissions to create/modify/drop *only* your database

How do I set permissions in SQL Server 2008 R2 such that the user can freely create, modify, and drop databases, but only their own - and can't read, see or modify anything else?
This can be done I guess by creating new user and not mapping any DBs created by other users.Hence this user can have permission to do anything with DBs created by him or her.

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.

Hide SQL database from Management Studio

How can you hide databases you do not have access rights to when logging into SQL Server 2005 / 2008?
Currently if a user connects, they see all the databases on the server, meaning they have to scan though the list to find their database.
After hours of trying to figure out how to create a user account which only has access to 1 DB, and can only see that DB. I think i figured it out!!!!
Create a user account ( make sure its not mapped to any Database, otherwise you will get the final error Msg 15110, Level 16, State 1 and note proposed solution)
USE [master]
GO
CREATE LOGIN [us4]
WITH PASSWORD=N'123',
DEFAULT_DATABASE=[master],
CHECK_EXPIRATION=OFF,
CHECK_POLICY=OFF
Right Click on the upper section of the SQL (SQLSERVER Name)>Properties>Permissions>Click on the user account, and select Deny to view databases.
use [master]
GO
DENY VIEW ANY DATABASE TO [us4]
Right Click on the newly created DB, Properties,Files, and change the Owner to the newly created account.(important note: ALTER ROLE [db_owner] ADD MEMBER [us4] does not work)
USE [dbname]
GO
EXEC dbo.sp_changedbowner #loginame = N'us4', #map = false
At this point, once the user logs in he will see the Master,tempdb and will also see the new DB which he is a DB Owner of..You may want to go to Tools>Option and enabled the option to hide system objects so that you don't show the master,tempdb,etc. You may also need SP1 if this option does not work
Msg 15110, Level 16, State 1, Line 1
The proposed new database owner is already a user or aliased in the database.
proposed solution to Msg 15110: to resolve above error simply delete the user from database security node and try again
Hope that helps...
Nikhil
This actually won't work the way that makes sense or that you might expect that it would.
You REVOKE VIEW ANY DATABASE from the public role, but then the user has to be the database owner of the database or it can't be seen, but it still can be accessed.
The problem is a Database Engine Security shortcoming and not likely to be fixed in the current or future release of SQL Server.
Erland Sommarskog opened the following connect item for this a while ago, and it recently was discussed on twitter and with Microsoft by the SQL MVP's.
Vote for the connect and help make it more of a priority for Microsoft to fix:
Connect Feedback
Basically the permissions are stored at the database level, so it would require enumerating each database to determine if the user has connect rights to display the database in the object explorer, which is an expensive task to perform and how the older EM used to do things.
The proposes solution is for this information to be maintained at the server level as well, which is a major change.
You would need to revoke the permission 'VIEW ANY DATABASE' from the role PUBLIC (SQL SERVER 2005 onwards)
Add user to DB as Db owner after removing VIEW ANY DATABASE rights
This will show only the database owned by the login in SSMS.
USE master; GO
DENY VIEW ANY DATABASE TO [loginname]; GO
USE [your db]; GO
DROP USER [loginname]; GO
USE master; GO
ALTER AUTHORIZATION ON DATABASE::[your db]TO [loginname]; GO
Note: this requires the login to exists already
There appears to be a server-side setting on MS SQL 2005 and 2008 to restrict the databases a user may see. I found the following text at sql-server-performance.com
In SQL Server 2005 it is possible with a new server side role that has been created. VIEW ANY DATABASE permission is a new, server-level permission. A login that is granted with this permission can see metadata that describes all databases, regardless of whether the login owns or can actually use a particular database. Please note By default, the VIEW ANY DATABASE permission is granted to the public role. Therefore, by default, every user that connects to an instance of SQL Server 2005 can see all databases in the instance.

Resources