【问题标题】:How to figure out list of users who have access to a given object in DB?如何找出有权访问数据库中给定对象的用户列表?
【发布时间】:2014-07-16 14:48:55
【问题描述】:

我正在尝试找出可用于获取对 SQL Server 2012 中给定对象、模式或数据库具有读取和或写入访问权限的所有用户列表的查询。我知道这是不可能知道的所有用户,因为某些用户通过 AD 组获得访问权限,这就是为什么我计划在知道 AD 组列表后从 Active Directory 获取最终用户列表的原因。

我查看了SQL Server query to find all permissions/access for all users in a database 的问题,但它太笼统了,我需要知道具有访问权限的特定 SQL 或 Windows 登录。

我想出了以下查询,但不确定我的逻辑是否正确。

SELECT u.name AS UserName
       ,o.name AS ObjectName
       ,o.type_desc AS ObjectType
       ,d.class_desc
       ,d.permission_name
       ,d.state
       ,d.state_desc
    FROM sys.database_permissions AS d
    JOIN sys.objects AS o
        ON d.major_id = o.parent_object_id
    JOIN sys.sysusers AS u
        ON d.grantee_principal_id = u.uid
           AND u.issqlrole = 0
    WHERE o.type_desc = 'USER_TABLE'
        AND o.name = 'MyTableName'

【问题讨论】:

    标签: sql-server sql-server-2012


    【解决方案1】:
    -- Script out permissions to all objects for a specific DB user 
    
    DECLARE @DatabaseUserName [sysname]
    SET @DatabaseUserName = 'domain\user-- Add whatever user name here 
    
    SET NOCOUNT ON`enter code here`
    DECLARE
    @errStatement [varchar](8000),
    @msgStatement [varchar](8000),
    @DatabaseUserID [smallint],
    @ServerUserName [sysname],
    @RoleName [varchar](8000),
    @ObjectID [int],
    @ObjectName [varchar](261)
    
    SELECT
    @DatabaseUserID = [sysusers].[uid],
    @ServerUserName = [master].[dbo].[syslogins].[loginname]
    FROM [dbo].[sysusers]
    INNER JOIN [master].[dbo].[syslogins]
    ON [sysusers].[sid] = [master].[dbo].[syslogins].[sid]
    WHERE [sysusers].[name] = @DatabaseUserName
    IF @DatabaseUserID IS NULL
    BEGIN
    SET @errStatement = 'User ' + @DatabaseUserName + ' does not exist in ' + DB_NAME() + CHAR(13) +
    'Please provide the name of a current user in ' + DB_NAME() + ' you wish to script.'
    RAISERROR(@errStatement, 16, 1)
    END
    ELSE
    BEGIN
    SET @msgStatement = '--Security creation script for user ' + @ServerUserName + CHAR(13) +
    '--Created At: ' + CONVERT(varchar, GETDATE(), 112) + REPLACE(CONVERT(varchar, GETDATE(), 108), ':', '') + CHAR(13) +
    '--Created By: ' + SUSER_NAME() + CHAR(13) +
    '--Add User To Database' + CHAR(13) +
    'USE [' + DB_NAME() + ']' + CHAR(13) +
    'EXEC [sp_grantdbaccess]' + CHAR(13) +
    CHAR(9) + '@loginame = ''' + @ServerUserName + ''',' + CHAR(13) +
    CHAR(9) + '@name_in_db = ''' + @DatabaseUserName + '''' + CHAR(13) +
    'GO' + CHAR(13) +
    '--Add User To Roles'
    PRINT @msgStatement
    DECLARE _sysusers
    CURSOR
    LOCAL
    FORWARD_ONLY
    READ_ONLY
    FOR
    SELECT
    [name]
    FROM [dbo].[sysusers]
    WHERE
    [uid] IN
    (
    SELECT
    [groupuid]
    FROM [dbo].[sysmembers]
    WHERE [memberuid] = @DatabaseUserID
    )
    OPEN _sysusers
    FETCH
    NEXT
    FROM _sysusers
    INTO @RoleName
    WHILE @@FETCH_STATUS = 0
    BEGIN
    SET @msgStatement = 'EXEC [sp_addrolemember]' + CHAR(13) +
    CHAR(9) + '@rolename = ''' + @RoleName + ''',' + CHAR(13) +
    CHAR(9) + '@membername = ''' + @DatabaseUserName + ''''
    PRINT @msgStatement
    FETCH
    NEXT
    FROM _sysusers
    INTO @RoleName
    END
    SET @msgStatement = 'GO' + CHAR(13) +
    '--Set Object Specific Permissions'
    PRINT @msgStatement
    DECLARE _sysobjects
    CURSOR
    LOCAL
    FORWARD_ONLY
    READ_ONLY
    FOR
    SELECT
    DISTINCT([sysobjects].[id]),
    '[' + USER_NAME([sysobjects].[uid]) + '].[' + [sysobjects].[name] + ']'
    FROM [dbo].[sysprotects]
    INNER JOIN [dbo].[sysobjects]
    ON [sysprotects].[id] = [sysobjects].[id]
    WHERE [sysprotects].[uid] = @DatabaseUserID
    OPEN _sysobjects
    FETCH
    NEXT
    FROM _sysobjects
    INTO
    @ObjectID,
    @ObjectName
    WHILE @@FETCH_STATUS = 0
    BEGIN
    SET @msgStatement = ''
    IF EXISTS(SELECT * FROM [dbo].[sysprotects] WHERE [id] = @ObjectID AND [uid] = @DatabaseUserID AND [action] = 193 AND [protecttype] = 205)
    SET @msgStatement = @msgStatement + 'SELECT,'
    IF EXISTS(SELECT * FROM [dbo].[sysprotects] WHERE [id] = @ObjectID AND [uid] = @DatabaseUserID AND [action] = 195 AND [protecttype] = 205)
    SET @msgStatement = @msgStatement + 'INSERT,'
    IF EXISTS(SELECT * FROM [dbo].[sysprotects] WHERE [id] = @ObjectID AND [uid] = @DatabaseUserID AND [action] = 197 AND [protecttype] = 205)
    SET @msgStatement = @msgStatement + 'UPDATE,'
    IF EXISTS(SELECT * FROM [dbo].[sysprotects] WHERE [id] = @ObjectID AND [uid] = @DatabaseUserID AND [action] = 196 AND [protecttype] = 205)
    SET @msgStatement = @msgStatement + 'DELETE,'
    IF EXISTS(SELECT * FROM [dbo].[sysprotects] WHERE [id] = @ObjectID AND [uid] = @DatabaseUserID AND [action] = 224 AND [protecttype] = 205)
    SET @msgStatement = @msgStatement + 'EXECUTE,'
    IF EXISTS(SELECT * FROM [dbo].[sysprotects] WHERE [id] = @ObjectID AND [uid] = @DatabaseUserID AND [action] = 26 AND [protecttype] = 205)
    SET @msgStatement = @msgStatement + 'REFERENCES,'
    IF LEN(@msgStatement) > 0
    BEGIN
    IF RIGHT(@msgStatement, 1) = ','
    SET @msgStatement = LEFT(@msgStatement, LEN(@msgStatement) - 1)
    SET @msgStatement = 'GRANT' + CHAR(13) +
    CHAR(9) + @msgStatement + CHAR(13) +
    CHAR(9) + 'ON ' + @ObjectName + CHAR(13) +
    CHAR(9) + 'TO ' + @DatabaseUserName
    PRINT @msgStatement
    END
    SET @msgStatement = ''
    IF EXISTS(SELECT * FROM [dbo].[sysprotects] WHERE [id] = @ObjectID AND [uid] = @DatabaseUserID AND [action] = 193 AND [protecttype] = 206)
    SET @msgStatement = @msgStatement + 'SELECT,'
    IF EXISTS(SELECT * FROM [dbo].[sysprotects] WHERE [id] = @ObjectID AND [uid] = @DatabaseUserID AND [action] = 195 AND [protecttype] = 206)
    SET @msgStatement = @msgStatement + 'INSERT,'
    IF EXISTS(SELECT * FROM [dbo].[sysprotects] WHERE [id] = @ObjectID AND [uid] = @DatabaseUserID AND [action] = 197 AND [protecttype] = 206)
    SET @msgStatement = @msgStatement + 'UPDATE,'
    IF EXISTS(SELECT * FROM [dbo].[sysprotects] WHERE [id] = @ObjectID AND [uid] = @DatabaseUserID AND [action] = 196 AND [protecttype] = 206)
    SET @msgStatement = @msgStatement + 'DELETE,'
    IF EXISTS(SELECT * FROM [dbo].[sysprotects] WHERE [id] = @ObjectID AND [uid] = @DatabaseUserID AND [action] = 224 AND [protecttype] = 206)
    SET @msgStatement = @msgStatement + 'EXECUTE,'
    IF EXISTS(SELECT * FROM [dbo].[sysprotects] WHERE [id] = @ObjectID AND [uid] = @DatabaseUserID AND [action] = 26 AND [protecttype] = 206)
    SET @msgStatement = @msgStatement + 'REFERENCES,'
    IF LEN(@msgStatement) > 0
    BEGIN
    IF RIGHT(@msgStatement, 1) = ','
    SET @msgStatement = LEFT(@msgStatement, LEN(@msgStatement) - 1)
    SET @msgStatement = 'DENY' + CHAR(13) +
    CHAR(9) + @msgStatement + CHAR(13) +
    CHAR(9) + 'ON ' + @ObjectName + CHAR(13) +
    CHAR(9) + 'TO ' + @DatabaseUserName
    PRINT @msgStatement
    END
    FETCH
    NEXT
    FROM _sysobjects
    INTO
    @ObjectID,
    @ObjectName
    END
    CLOSE _sysobjects
    DEALLOCATE _sysobjects
    PRINT 'GO'
    END
    

    【讨论】:

      猜你喜欢
      • 2018-02-20
      • 2020-02-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多