是否可以拒绝具有db_owner角色成员身份的登录用户的RESTORE权限?
在使用该数据库的备份还原现有数据库时,是否需要dbcreator权限?或者只有在从备份创建新数据库时才需要?
我想防止一个具有db_owner成员身份的用户意外地将数据库还原到错误的服务器/实例上。
是否可以拒绝具有db_owner角色成员身份的登录用户的RESTORE权限?
在使用该数据库的备份还原现有数据库时,是否需要dbcreator权限?或者只有在从备份创建新数据库时才需要?
我想防止一个具有db_owner成员身份的用户意外地将数据库还原到错误的服务器/实例上。
关于数据库权限,Microsoft RESTORE statement Docs中提到:
如果要恢复的数据库不存在,则用户必须具有CREATE DATABASE权限才能执行RESTORE操作。如果数据库已存在,则RESTORE权限默认为sysadmin和dbcreator固定服务器角色的成员以及数据库所有者(dbo)。
RESTORE权限授予的是在服务器上始终可以轻松获取成员信息的角色。由于只有在数据库可访问且未损坏时才能检查固定数据库角色成员资格,而这在执行RESTORE操作时并不总是适用,因此db_owner固定数据库角色的成员没有RESTORE权限。
我建议将需要db_owner级别权限的人员与实际数据库所有者分开作为独立的登录账户。加入db_owner数据库角色会阻止该用户执行恢复操作。
通过拒绝CREATE ANY DATABASE权限,可以防止登录账户执行RESTORE DATABASE操作。
作为测试,我在我的SQL Server 2008 R2实例上进行了此操作。
创建一个测试登录账号:USE master;
GO
IF NOT EXISTS (SELECT 1 FROM sys.server_principals sp WHERE sp.name = 'Test_db_owner')
BEGIN
CREATE LOGIN Test_db_owner WITH PASSWORD = 'awsdaqwer0987)(FA&897afda2345';
END
GO
创建一个测试数据库:
IF EXISTS (SELECT 1 FROM sys.databases d WHERE d.name = 'Test_db_owner')
BEGIN
ALTER DATABASE Test_db_owner SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
DROP DATABASE Test_db_owner;
END
CREATE DATABASE Test_db_owner;
GO
在上述登录中为测试数据库创建一个用户,并将该用户添加到db_owner数据库角色中:
USE Test_db_owner;
CREATE USER [Test_db_owner] FOR LOGIN [Test_db_owner];
EXEC sys.sp_addrolemember @rolename = 'db_owner', @membername = 'Test_db_owner';
GO
创建数据库备份。
USE master;
BACKUP DATABASE Test_db_owner TO DISK = 'D:\SQLServer\MV\Backup\Test_db_owner.bak' WITH INIT;
测试恢复语句作为登录:
EXECUTE AS LOGIN = 'Test_db_owner';
RESTORE DATABASE Test_db_owner FROM DISK = 'D:\SQLServer\MV\Backup\Test_db_owner.bak'
WITH REPLACE, RECOVERY;
REVERT;
输出:
Msg 3110,级别14,状态1,行25 用户没有权限还原数据库'Test_db_owner'。 Msg 3013,级别16,状态1,行25 还原数据库异常终止。
清理:
DROP LOGIN Test_db_owner;
DROP DATABASE Test_db_owner;
FYI,数据库所有者已更改如下:
ALTER AUTHORIZATION ON DATABASE::[xyz] TO [login_name];
(或者使用sys.sp_changedbowner,它已被弃用)。
db_owner角色的成员权限如下所示:
ALTER ROLE [db_owner] ADD MEMBER [login_name];
虽然这两个语句似乎影响"数据库所有者",但事实并非如此;只有ALTER AUTHORIZATION语句可以修改登录的数据库所有权。请参阅Remus Rusanu的这个出色的答案。
如果您想允许登录在非生产环境中恢复数据库,请将其添加到dbcreator服务器角色成员中。
EXEC sys.sp_addsrvrolemember @loginame = 'Test_db_owner'
, @rolename = 'dbcreator';