首页 - 信息 - SQL Server数据库检查登录名授予的具体权限

SQL Server数据库检查登录名授予的具体权限

2023-10-02 08:26

如何检查SQL Server数据库中某个登录名(login)的具体权限?如果使用SSMS的UI界面来查看登录名的具体权限,用户数据库有很多,如果想把它的所有权限都整理出来,操作起来既费时又麻烦。我个人崇尚简洁高效的方法,不喜欢那些需要大量手动操作的UI界面操作方法,哪怕是脚本。如果不能一次性完成,可以手动多次完成。多次(例如切换数据库),两者都是不可接受的。最近遇到这个需求时,我改进了之前的脚本get_login_rights_script.sql,输入登录名参数,通过脚本查询该登录名所拥有的特定对象所授予的服务器角色、数据库角色以及相关权限。脚本分享如下:

--================================================ =================================================== ===================
-- 脚本名称:get_login_rights_script.sql
——作者:潇湘隐士
--创建日期:2015-12-18
-- 说明:查看某个登录名授予的数据库对象权限的脚本(授权脚本和权限恢复脚本)
 -  笔记:
/******************************************************** ***** ************************************************* ****** **************
    参数:参数说明
****************************************************** ********************************************************* ** ******************@login_name:您要检查权限的登录名(需要输入替换参数)
****************************************************** ********************************************************* ** ******************
  修改日期 修改用户版本 修改原因
****************************************************** ********************************************************* ** ******************
  2018-08-03 潇湘隐士V01.00.00 新建脚本。
  2019-04-04 潇湘隐士 V01.01.00 修复bug。某个表只允许更新某个字段,但这里显示的是整个表。
  2019-09-25 潇湘隐者V01.02.00 解决权限只能查看某个用户数据库,而不能查看所有数据库的问题。
  2019-09-25 潇湘隐者V01.03.00 解决数据库名包含破折号[-]而出现以下错误的问题
-------------------------------------------------- -------------------------------------------------- ----------------
消息 911,16 级,状态 1,第 1 行
数据库“xxxx”不存在。确保输入的名称正确。
-------------------------------------------------- -------------------------------------------------- ----------------****************************************************** ****************************************************** **************/
声明 @login_name NVARCHAR(32)= 'test1';
声明 @database_name NVARCHAR(64);
声明 @cmdText NVARCHAR(MAX);
IF OBJECT_ID('TempDB.dbo.#databases') IS NOT NULL
  删除表 dbo.#databases;
创建表#databases
(
  数据库 ID INT,
  数据库名称 系统名称
);
IF OBJECT_ID('tempdb.dbo.#user_db_roles') IS NOT NULL
  删除表 dbo.#user_db_roles;
创建表 dbo.#user_db_roles
(
   [DB_NAME] NVARCHAR(64)
  ,[用户名] NVARCHAR(64)
  ,[角色名称] NVARCHAR(64)
);
IF OBJECT_ID('tempdb.dbo.#user_object_rights') IS NOT NULL
  删除表 dbo.#user_object_rights;
创建表 dbo.#user_object_rights
(
  [DATABASE_NAME] NVARCHAR(128),
  [SCHEMA_NAME] NVARCHAR(64),
  [OBJECT_NAME] NVARCHAR(128),
  [USER_NAME] NVARCHAR(32),
  [权限类型] CHAR(12),[PERMISSION_NAME] NVARCHAR(128),
  [权限状态] NVARCHAR(64),
  [CLASS_DESC] NVARCHAR(64),
  [COLUMN_NAME] NVARCHAR(32),
  [STATE_DESC] NVARCHAR(64),
  [GRANT_STMT] NVARCHAR(最大值),
  [REVOKE_STMT] NVARCHAR(最大值)
)
插入#databases
选择数据库id,
    姓名
来自系统数据库
WHERE 名称 NOT IN ('model') AND state = 0; --state_desc=在线
--登录名拥有的服务器角色
选择用户名 = www.gsm-guard.net ,
    服务器角色 = www.gsm-guard.net ,
    类型 = u.type,
    类型_描述 = u.类型_描述,
    创建日期 = u.创建日期,
    修改日期 = u.修改日期,
    DenyLogin = l.denylogin
来自 sys.server_role_members m
    内连接 sys.server_principals g ON g.principal_id = m.role_principal_id
    内连接 sys.server_principals u ON u.principal_id = m.member_principal_id
    内连接 sys.syslogins l ON www.gsm-guard.net = www.gsm-guard.net
WHERE www.gsm-guard.net=@login_name
按 www.gsm-guard.net,www.gsm-guard.net 排序;
而 1= 1
开始选择前 1 @database_name=database_name
  来自#databases
  按数据库 ID 排序;
  如果@@ROWCOUNT =0
    休息;
  SET @cmdText = N'USE ' + QUOTENAME(@database_name) + N';' +字符(10)
  --登录名拥有的数据库角色
  SELECT @cmdText += N'INSERT INTO #user_db_roles
            选择 DB_NAME() 作为 [DB_NAME]
                ,www.gsm-guard.net AS [USER_NAME]
                ,www.gsm-guard.net AS [ROLE_NAME]
            来自 sys.DATABASE_ROLE_MEMBERS RM
                内连接 sys.DATABASE_PRINCIPALS R ON RM.ROLE_PRINCIPAL_ID = R.PRINCIPAL_ID
                INNER JOIN sys.DATABASE_PRINCIPALS M ON RM.MEMBER_PRINCIPAL_ID = M.PRINCIPAL_ID
            WHERE www.gsm-guard.net=@p_login_name' + CHAR(10);
  EXEC SP_EXECUTESQL @cmdText, N'@p_login_name NVARCHAR(32)',@p_login_name=@login_name;
  SET @cmdText = N'USE ' +QUOTENAME(@database_name) + N';' +CHAR(10);
  --查看具体对象的授权问题
  SELECT @cmdText +=N'INSERT INTO dbo.#user_object_rights
            (  [数据库名称]   ,[SCHEMA_NAME],
              [OBJECT_NAME],
              [用户名]     ,
              [权限类型],
              [PERMISSION_NAME],
              [权限状态],
              [CLASS_DESC] ,
              [COLUMN_NAME],
              [状态_DESC],
              [授予STMT],
              [撤销_STMT]
            )
            选择 DB_NAME() 作为 [DATABASE_NAME]
               , www.gsm-guard.net AS [SCHEMA_NAME]
               , www.gsm-guard.net AS [OBJECT_NAME]
               , SYS.DATABASE_www.gsm-guard.net AS [USER_NAME]
               , dp.TYPE AS [PERMISSIONS_TYPE]
               , dp.PERMISSION_NAME AS [PERMISSION_NAME]
               , dp.STATE AS [PERMISSION_STATE]
               , dp.CLASS_DESC AS [CLASS_DESC]
               , www.gsm-guard.net AS [COLUMN_NAME], dp.STATE_DESC AS [STATE_DESC]
               , dp.STATE_DESC + '' '' + dp.PERMISSION_NAME + '' ON [''+ www.gsm-guard.net + ''].['' + www.gsm-guard.net + ''] TO ['' + SYS.DATABASE_PRINCIPALS .NAME + ''];'' 整理 LATIN1_GENERAL_CI_AS
                               作为[GRANT_STMT]
               , ''REVOKE '' + dp.PERMISSION_NAME + '' ON [''+ www.gsm-guard.net + ''].['' + www.gsm-guard.net + ''] FROM ['' + SYS.DATABASE_www.gsm-guard.net + ''];'' 整理 LATIN1_GENERAL_CI_AS
                               作为[REVOKE_STMT]
            来自 SYS.DATABASE_PERMISSIONS dp
            左外连接 SYS.OBJECTS ob ON dp.MAJOR_ID = ob.OBJECT_ID
            ob.SCHEMA_ID = SYS.SCHEMAS.SCHEMA_ID 上的左外连接 SYS.SCHEMAS
            左外连接 SYS.DATABASE_PRINCIPALS ON dp.GRANTEE_PRINCIPAL_ID = SYS.DATABASE_PRINCIPALS.PRINCIPAL_ID左外连接 SYS.columns sc ON ob.object_id = sc.object_id AND sc.column_id = dp.minor_id
            WHERE SYS.DATABASE_www.gsm-guard.net =@p_login_name
            按权限类型排序;'
  打印(@cmdText);
  EXEC SP_EXECUTESQL @cmdText, N'@p_login_name NVARCHAR(32)',@p_login_name=@login_name;
  从#databases 中删除,其中database_name=@database_name;
结尾
从 tempdb.dbo.#user_db_roles 中选择*;
从 dbo.#user_object_rights 中选择*;
IF OBJECT_ID('TempDB.dbo.#databases') IS NOT NULL
  删除表 dbo.#databases;
IF OBJECT_ID('tempdb.dbo.#user_db_roles') IS NOT NULL
  删除表 dbo.#user_db_roles;
IF OBJECT_ID('tempdb.dbo.#user_object_rights') IS NOT NULL
  删除表 dbo.#user_object_rights;

总结

以上是小编介绍的SQL Server授予查看登录的具体权限。希望对大家有帮助,