无法撤消其他用户授予的权限

时间:2014-01-21 06:51:42

标签: sql-server sql-server-2008 tsql

Microsoft SQL Server 2008(SP3) - 10.0.5500.0(X64)     2011年9月21日22:45:45     版权所有(c)1988-2008 Microsoft Corporation     Windows NT 6.1(Build 7601:Service Pack 1)上的企业版(64位)

我在我的数据库中有一个存储过程,并且user1将该proc的exec权限授予其他user2。 所以user1是授予者。

现在我(作为SA)尝试从user2撤消此权限。

revoke exec on sp from user2

我得到了

Command(s) completed successfully.

但我仍然可以看到授予的权限!

SELECT object_name(id), user_name(uid) FROM sysprotects WHERE grantor = USER_ID('user1')

我做错了什么?

3 个答案:

答案 0 :(得分:0)

你试过了吗?

revoke exec on sp from user2 as user1

答案 1 :(得分:0)

您是否已将action列添加到sysprotects? 也许有一个额外的权限已被授予user1?!

;with "action"
as
(
select "actionid" = 26, "description"='REFERENCES' union all 
select 178, 'CREATE FUNCTION' union all 
select 193, 'SELECT' union all 
select 195, 'INSERT' union all 
select 196, 'DELETE' union all 
select 197, 'UPDATE' union all 
select 198, 'CREATE TABLE' union all 
select 203, 'CREATE DATABASE' union all 
select 207, 'CREATE VIEW' union all 
select 222, 'CREATE PROCEDURE' union all 
select 224, 'EXECUTE' union all 
select 228, 'BACKUP DAABASE' union all 
select 233, 'CREATE DEFAULT' union all 
select 235, 'BACKUP LOG' union all 
select 236, 'CREATE RULE'
)
select object_name(id), user_name(uid), A.description FROM sysprotects SP 
inner join "action" A
    on A."actionid" = SP."action"
where grantor = USER_ID('user1')

答案 2 :(得分:0)

GRANT和REVOKE是非常复杂的结构命令,有时很难跟踪所有小细节。如果您可以发布您运行的查询以授予用户执行权限,那么这将是任何ServerRole的用户成员吗?你是否使用GRANT命令和GRANT选项?

从您的描述和其他评论我看到User_1是授予者,如果是DB_Owner,则表示它具有所有权限。那么User_2怎么样?它是任何服务器角色的成员吗?

尝试以下脚本。它只是在SQL 2008-R2-SP1上演示了GRANT和REVOKE预期的行为。 在这个例子中,dbo是granter,user1是被授予者。

查看输出图像前两行输出显示正在执行该过程的用户。但在User_1上执行撤销后,我们收到了错误消息。

另外,在GRANT之后,我可以在撤销后看到sysprotect ut中的recird,我没有看到user1的任何记录。

    --Creating a Procedure
    IF Object_ID('Pr_TestUserPermission') IS NOT NULL
        DROP PROCEDURE Pr_TestUserPermission
    GO
    CREATE PROC Pr_TestUserPermission
    AS
    BEGIN
        PRINT 'This Procedure is currently executed under user ' + USER_NAME()
    END
    GO

    --Granting another User Exec permission of this proc
    GRANT EXEC ON Pr_TestUserPermission TO user1
    SELECT object_name(id), user_name(uid) FROM sysprotects WHERE user_name(uid) = 'User1'

    --Executing the procedure as Original User
    EXECUTE Pr_TestUserPermission

    --Change the Executer User Context to User1 and then Try to Call same Procedure
    EXECUTE AS LOGIN='User1'
    EXECUTE Pr_TestUserPermission
    REVERT


    --Revoke the Grant permission
    REVOKE EXEC ON Pr_TestUserPermission FROM user1
    SELECT object_name(id), user_name(uid) FROM sysprotects WHERE grantor = USER_ID('user1')


    --Change the Executer again back to User1 and Try to Call same Procedure
    EXECUTE AS LOGIN='User1'
    EXECUTE Pr_TestUserPermission
    REVERT 

enter image description here enter image description here

修改:1

我找到了有趣的理由。这是REVOKE语句的语法。 检查以下示例。在此示例中,user1是db owner和Granter,而user2是被授予者。

检查输出。图片如下。 使用通用语法“REVOKE EXEC ON SP FROM USER2”更新sysprotect但实际上不撤消权限。但是如果我们使用另一个syntex“REVOKE EXEC ON OBJECT :: SP From user2”那么它会实际撤销权限,我们可以在下面的结果中看到。

设置NOCOUNT

    --Creating a Procedure
    IF Object_ID('Pr_TestUserPermission2') IS NOT NULL
        DROP PROCEDURE Pr_TestUserPermission2
    GO
    CREATE PROC Pr_TestUserPermission2
    AS
    BEGIN
        PRINT 'This Procedure is currently executed under user ' + USER_NAME()
    END
    GO

    --Granting another User Exec permission of this proc
    GRANT EXEC ON Pr_TestUserPermission2 TO user2
    SELECT object_name(id), user_name(uid) FROM sysprotects WHERE user_name(uid) = 'User2'

    --Executing the procedure as Original User
    EXECUTE Pr_TestUserPermission2

    --Change the Executer User Context to User1 and then Try to Call same Procedure
    EXECUTE AS USER='user2'
    EXECUTE Pr_TestUserPermission2
    REVERT


    --Revoke the Grant permission using common syntex
    REVOKE EXECUTE ON Pr_TestUserPermission FROM user2
    SELECT object_name(id), user_name(uid) FROM sysprotects WHERE grantor = USER_ID('user2')


    --Change the Executer again back to User1 and Try to Call same Procedure
    EXECUTE AS USER='user2'
    EXECUTE Pr_TestUserPermission2
    REVERT


    --Revoke the Grant permission using another sytex
    REVOKE EXECUTE ON OBJECT::dbo.Pr_TestUserPermission2 FROM user2
    SELECT object_name(id), user_name(uid) FROM sysprotects WHERE grantor = USER_ID('user2')

    --Change the Executer again back to User1 and Try to Call same Procedure
    EXECUTE AS USER='user2'
    EXECUTE Pr_TestUserPermission2
    REVERT 

enter image description here