对象“TheTable”、数据库“TheDb”、架构“dbo”的插入/更新/删除权限被拒绝

Dud*_*lou 7 sql-server permissions sql-server-2008-r2

我在一个数据库上有两个 SQL Server 用户帐户,它们在INSERT / UPDATE / DELETE. SQL Server 版本为 2008 R2(10.50.4042,64 位)。

UserA可以执行这些命令(在任何表上)。它是一个 SQL Server“本地”帐户(SQL Server 登录名,而不是本地服务器上的 Windows 帐户)。

DOMAIN\UserB,不能。它来自 Windows AD 帐户。它是数据库服务器上管理员组的成员。

它得到错误:

对象“TheTable”、数据库“TheDb”、架构“dbo”的插入/更新/删除权限被拒绝

据我所知,这两个账户的角色是一样的。
这些角色之一具有INSERT/UPDATE/DELETE对表的权限。
帐户不是角色的成员db_denydatawriter

我试图为 UserB 明确授予权限:

GRANT SELECT, UPDATE, DELETE, INSERT on TheTable TO [DOMAIN\UserB]
Run Code Online (Sandbox Code Playgroud)

但我仍然有错误。

如果我sysadmin在 UserB 上添加角色,当然它有权限,但我不想让它有这个角色。

所以,对我来说,唯一的区别是local account / Windows AD account

您知道一种获取有关潜在 Windows AD 帐户特定权限的更多信息的方法吗?

经过更多研究,我怀疑UserB具有未经许可的角色。这个Stack Overflow 答案让我走上了正轨。这是一个查询,显示:

-- Users that are members of roles without any permission :
select *
from sys.database_role_members members 
left outer join sys.database_principals memberprinc on memberprinc.[principal_id] = members.[member_principal_id]
left outer join sys.database_principals roleprinc ON roleprinc.[principal_id] = members.[role_principal_id]
where members.role_principal_id in
(
    -- Roles without any permission :
    select principal_id
    from sys.database_principals roleprinc
    where not exists 
    (
        select * 
        from sys.database_permissions perm 
        where perm.[grantee_principal_id] = roleprinc.[principal_id])
)
and memberprinc.name = 'DOMAIN\UserB'
Run Code Online (Sandbox Code Playgroud)

但是我无法编辑这些表(即使具有 sysadmin 角色),这是可以理解的。

消息 259 不允许对系统目录进行临时更新。

我注意到UserAUserB之间的另一个区别:在 TheDb 属性上,选项卡权限,子选项卡有效:

有效权限

我发现(来自 SQL Server Profiler)该列表来自以下查询:

EXECUTE AS LOGIN = N'DOMAIN\UserB';
SELECT 
    permission_name AS [Permission]
FROM fn_my_permissions(N'[TheDb]', N'DATABASE')
ORDER BY permission_name;
REVERT;
Run Code Online (Sandbox Code Playgroud)

你知道如何追踪这些权限的来源吗?

正如评论中所建议的,我列出了UserAUserBDENY权限:

SELECT [dp].[name] AS [user_name], [dpr].[name] AS [role_name], [per].[permission_name], [per].[state_desc], OBJECT_NAME([major_id]) AS [object_name]
FROM [sys].[database_principals] AS [dp] 
INNER JOIN [sys].[database_role_members] AS [drm] ON [dp].[principal_id] = [drm].[member_principal_id] 
INNER JOIN [sys].[database_principals] AS [dpr] ON [drm].[role_principal_id] = [dpr].[principal_id] 
INNER JOIN [sys].[database_permissions] AS [per] ON [dpr].[principal_id] = [per].[grantee_principal_id] 
WHERE [dp].[name] in ('DOMAIN\UserB', 'UserA') AND [per].[state_desc] = 'DENY'
ORDER BY [dp].[name];
Run Code Online (Sandbox Code Playgroud)

这两个用户DENY对两个对象具有完全相同的权限:

user_name role_name permission_name state_desc object_name
-------------------------------------------------- -------------
UserA RoleC REFERENCES DENY ObjectD
UserA RoleC REFERENCES DENY ObjectE
域\用户B 角色C 引用拒绝对象D
域\用户B 角色C 引用拒绝对象E

有人有更多线索吗?

SELECT SUSER_NAME()做回DOMAIN\UserB我的身份登录DOMAIN\UserB

Unn*_*n R -1

尝试使用下面的脚本。它对我有用。

GRANT SELECT ,UPDATE,DELETE,INSERT ON OBJECT::YourTable  
    TO [Domain\User];  
GO   
Run Code Online (Sandbox Code Playgroud)

我尝试向数据库 MyLab 中的用户 Anoop 授予上述权限。

GRANT SELECT ,UPDATE,DELETE,INSERT ON OBJECT::Account  
    TO [*MyDomain*\anoop];  
GO   
Run Code Online (Sandbox Code Playgroud)

下面是授予许可后的屏幕截图。

在此输入图像描述

  • 感谢您的回答。你是对的,这个命令应该有效,就像我在OP中所说的那样。但它没有,出于我不知道的原因...... (4认同)