Sql-Server

在沒有伺服器角色 dbcreator 的情況下,授予使用者訪問權限以還原他們擁有的數據庫

  • July 24, 2021

外部供應商的 SQL 使用者擁有db_owner兩個數據庫(實時數據庫和培訓數據庫)的權限。他們不時希望能夠在訓練的基礎上進行實時備份和恢復。最簡單的方法是授予他們伺服器角色dbcreator,但這將允許他們刪除他們通常無法訪問的數據庫。現在他們可以從現場進行備份,但恢復到他們得到的訓練:

執行 Transact-SQL 語句或批處理時發生異常:

數據庫“主”中的 CREATE DATABASE 權限被拒絕

RESTORE HEADERONLY 異常終止

有沒有辦法讓這個使用者訪問恢復數據庫,而不給他們伺服器角色dbcreator或給他們該權限,但然後將範圍限制為他們應該有權訪問的兩個數據庫?

您可以通過保證帳戶供應商正在使用的除了這兩個之外的任何數據庫中沒有相應的使用者來做到這一點。

CREATE ANY DATABASE將授予供應商執行所需還原的權限。

下面的程式碼將展示使用者vendor不能刪除數據庫。

CREATE LOGIN vendor
 WITH PASSWORD = N'Change_Password',
 CHECK_POLICY = OFF;
GO

GRANT CREATE ANY DATABASE TO vendor
GO

USE master;
GO
IF  EXISTS (
   SELECT name 
       FROM sys.databases 
       WHERE name = N'live'
)
DROP DATABASE live;
GO
CREATE DATABASE live;
GO

ALTER AUTHORIZATION ON DATABASE::live TO vendor;
GO

USE master;
GO

IF  EXISTS (
   SELECT name 
       FROM sys.databases 
       WHERE name = N'training'
)
DROP DATABASE training;
GO

CREATE DATABASE training;
GO

ALTER AUTHORIZATION ON DATABASE::training TO vendor;
GO

USE master;
GO
IF  EXISTS (
   SELECT name 
       FROM sys.databases 
       WHERE name = N'cannotdropme'
)
DROP DATABASE cannotdropme;
GO
CREATE DATABASE cannotdropme;
GO

EXECUTE AS LOGIN = 'vendor';  
SELECT SUSER_NAME(), USER_NAME();  

BACKUP DATABASE live
   TO  DISK = N'C:\Program Files\Microsoft SQL Server\MSSQL15.MSSQLSERVER\MSSQL\Backup\live.bak' 
WITH 
   NOFORMAT, 
   COMPRESSION,
   NOINIT,  
   NAME = N'live-Full Database Backup', 
   SKIP, 
   STATS = 10;
GO

USE [master]

RESTORE DATABASE [training] FROM  DISK = N'C:\Program Files\Microsoft SQL Server\MSSQL15.MSSQLSERVER\MSSQL\Backup\live.bak'
WITH  FILE = 1,  
MOVE N'Live' TO N'C:\Program Files\Microsoft SQL Server\MSSQL15.MSSQLSERVER\MSSQL\DATA\training.mdf',  
MOVE N'Live_log' TO N'C:\Program Files\Microsoft SQL Server\MSSQL15.MSSQLSERVER\MSSQL\DATA\training_log.ldf',  
NOUNLOAD,  REPLACE,  STATS = 5
GO

--Cannot drop this database as user verndor is not a user in this database
DROP DATABASE cannotdropme;
GO

REVERT;  
SELECT SUSER_NAME(), USER_NAME();  

DROP DATABASE live;
DROP DATABASE training; 
DROP DATABASE cannotdropme;
DROP LOGIN vendor;  
GO

引用自:https://dba.stackexchange.com/questions/296090