12. 查询数据库账号的所有权限
2015-09-30 13:21
543 查看
在SQL Server数据库中,登录账号分类如下:
(1) SQL账号,需要单独设置密码,比如:sa;
(2) Windows账号,登录windows的账号,比如: administrator,不需要另设密码;
(3) Windows Group 账号, 为本地用户组或域用户组,将组添加到登录,组成员不需要单独创建登录;
查看Windows账号,是否属于某一个/多个用户组:
以下脚本,均假设最终登录账号为:test_login,所有数据库对应的user为test_user
[b]一. 有没有权限[/b]
1. 检查有没有登录权限
2. 检查有没有访问某数据库的权限
如果有很多个数据库,写个游标1个个去检查即可。
3. 检查有没有某个对象的权限
检查有没有某个对象的权限,一般是去尝试运行下脚本比较直观,如果去查各种权限表,角色错综复杂时,很难分辨;
SQL Server 2008之后引入了HAS_PERMS_BY_NAME这个函数,它可以检查当前账号的各种权限,检查其他用户需要用EXECUTE AS来切换:
对于是否有登录、访问数据库的权限,用这个函数也可以判断:
[b]二. 有哪些权限[/b]
权限可以直接分配给账号,也可以分配给账号所属的role,所以要把账号自身权限、所属role权限合并才是最终的账号权限。
Windows账号权限还可以通过用户组分配,所以还要检查这个Windows账号有没有属于某个用户组,如果有还需要加上这个用户组的权限;
下面的脚本,仅检查单个用户/用户组权限。
1. 实例级的权限
Object-Level Permissions
注意:如果对象的权限是通过role衍生的,而不是直接分配给user或者role,那么并不会被列出来。试想sysadmin 的角色,难道要列出所有数据库的所有对象吗?
[b]三. 查看自己的权限[/b]
1. 有没有登录权限
登录失败并不一定是没权限,还是找别人来检查自己账号的登录权限吧;
2. 有没有数据库访问权限
3. 有没有对象访问权限
用上面提到HAS_PERMS_BY_NAME函数,它可以检查当前账号的各种权限;
4. 有哪些权限
用于检查自己权限的方法,同样也可以检查其他账号,用EXECUTE AS切换账号即可。
(1) SQL账号,需要单独设置密码,比如:sa;
(2) Windows账号,登录windows的账号,比如: administrator,不需要另设密码;
(3) Windows Group 账号, 为本地用户组或域用户组,将组添加到登录,组成员不需要单独创建登录;
查看Windows账号,是否属于某一个/多个用户组:
exec xp_logininfo 'windows_acount','ALL' --域用户格式为:domain_name\account_name
以下脚本,均假设最终登录账号为:test_login,所有数据库对应的user为test_user
[b]一. 有没有权限[/b]
1. 检查有没有登录权限
--是否存在有效的登录账号:是否被禁用,sql login还有:密码是否过期,是否被锁定 select is_disabled, loginproperty(name,'Isexpired') is_expired, loginproperty(name,'Islocked') is_locked, * from sys.server_principals where name = 'test_login'
2. 检查有没有访问某数据库的权限
USE DBA GO --检查是否有数据库的CONNECT权限即可 select b.* from sys.database_principals a inner join sys.database_permissions b on a.principal_id = b.grantee_principal_id where SUSER_SNAME(a.sid) = 'test_login' and b.permission_name = 'CONNECT' --老的系统表sysusers也可以检查 SELECT name, hasdbaccess,* FROM sysusers a WHERE SUSER_SNAME(a.sid) = 'test_login'
如果有很多个数据库,写个游标1个个去检查即可。
3. 检查有没有某个对象的权限
检查有没有某个对象的权限,一般是去尝试运行下脚本比较直观,如果去查各种权限表,角色错综复杂时,很难分辨;
SQL Server 2008之后引入了HAS_PERMS_BY_NAME这个函数,它可以检查当前账号的各种权限,检查其他用户需要用EXECUTE AS来切换:
USE DBA GO EXECUTE AS user = 'test_user' GO --对象权限 SELECT HAS_PERMS_BY_NAME('Sales.SalesPerson', 'OBJECT', 'INSERT'); SELECT HAS_PERMS_BY_NAME('sp_send_dbmail', 'OBJECT', 'EXEC'); --架构权限 SELECT HAS_PERMS_BY_NAME('test_schema', 'SCHEMA', 'SELECT'); REVERT; GO
对于是否有登录、访问数据库的权限,用这个函数也可以判断:
USE master GO EXECUTE AS login = 'test_login' GO --登录权限,本机前2个参数为空即可 SELECT HAS_PERMS_BY_NAME(NULL, NULL, 'CONNECT SQL'); REVERT; GO USE DBA GO EXECUTE AS user = 'test_user' GO --数据库权限 SELECT HAS_PERMS_BY_NAME(db_name(), 'DATABASE', 'CONNECT'); REVERT;
[b]二. 有哪些权限[/b]
权限可以直接分配给账号,也可以分配给账号所属的role,所以要把账号自身权限、所属role权限合并才是最终的账号权限。
Windows账号权限还可以通过用户组分配,所以还要检查这个Windows账号有没有属于某个用户组,如果有还需要加上这个用户组的权限;
下面的脚本,仅检查单个用户/用户组权限。
1. 实例级的权限
--建立测试用的架构,对象,列 use DBA GO if object_id('test_grant','U') is not null drop table test_grant GO create table test_grant(c1 int, c2 int, c3 int) grant select (c1, c2) on test_grant to test_user; if object_id('test_schema.test_t1','U') is not null drop table test_schema.test_t1 GO if exists(select 1 from sys.schemas where name = 'test_schema') drop schema test_schema GO create schema test_schema create table test_schema.test_t1(c1 int, c2 int) grant select on schema::test_schema to test_user; GO --开始获取对象权限 use DBA GO declare @svr_principal_name varchar(1024) set @svr_principal_name = 'test_login' declare @db_principal_id int, @db_principal_name varchar(512) select @db_principal_id = principal_id, @db_principal_name = name from sys.database_principals p where SUSER_SNAME(sid) = @svr_principal_name if OBJECT_ID('tempdb..#tmp_db_role','U') is not null drop table #tmp_db_role; create table #tmp_db_role ( member_principal_id int, member_principal_name varchar(512), role_principal_id int, role_principal_name varchar(512) ) --获取登录账号在当前数据库的所有database role ;with tmp as ( select * from sys.database_role_members where member_principal_id = @db_principal_id union all select rm.* from sys.database_role_members rm inner join tmp on rm.member_principal_id = tmp.role_principal_id ) insert into #tmp_db_role select a.member_principal_id, b.name, a.role_principal_id, c.name from tmp a inner join sys.database_principals b on a.member_principal_id = b.principal_id inner join sys.database_principals c on a.role_principal_id = c.principal_id --登录账号在当前数据库的自身对象权限(OBJECT_OR_COLUMN) select a.principal_id as member_principal_id, a.name as member_principal_name, null as role_principal_id, null as role_principal_name, o.name as major_name, c.name as minor_name, b.permission_name, b.state_desc from sys.database_principals a inner join sys.database_permissions b on a.principal_id = b.grantee_principal_id left join sys.objects o on b.major_id = o.object_id left join sys.columns c on (b.major_id = c.object_id and b.minor_id = c.column_id) where a.principal_id = @db_principal_id and b.class_desc = 'OBJECT_OR_COLUMN' union all --登录账号在当前数据库的自身对象权限(SCHEMA) select a.principal_id as member_principal_id, a.name as member_principal_name, null as role_principal_id, null as role_principal_name, s.name as major_name, null as minor_name, b.permission_name, b.state_desc from sys.database_principals a inner join sys.database_permissions b on a.principal_id = b.grantee_principal_id left join sys.schemas s on b.major_id = s.schema_id where a.principal_id = @db_principal_id and b.class_desc = 'SCHEMA' union all --database role的对象权限(OBJECT_OR_COLUMN) select a.member_principal_id, a.member_principal_name, a.role_principal_id, a.role_principal_name, o.name as major_name, c.name as minor_name, b.permission_name, b.state_desc from #tmp_db_role a inner join sys.database_permissions b --inner join, 仅自定义的database role on a.role_principal_id = b.grantee_principal_id left join sys.objects o on b.major_id = o.object_id left join sys.columns c on (b.major_id = c.object_id and b.minor_id = c.column_id) where b.class_desc = 'OBJECT_OR_COLUMN' union all --database role的对象权限(SCHEMA) select a.member_principal_id, a.member_principal_name, a.role_principal_id, a.role_principal_name, s.name as major_name, null as minor_name, b.permission_name, b.state_desc from #tmp_db_role a inner join sys.database_permissions b --inner join, 仅自定义的database role on a.role_principal_id = b.grantee_principal_id left join sys.schemas s on b.major_id = s.schema_id where b.class_desc = 'SCHEMA' /* union all --public role有一些系统视图的select权限,可以忽略 select a.principal_id as member_principal_id, a.name as member_principal_name, null as role_principal_id, null as role_principal_name, o.name as major_name, c.name as minor_name, b.permission_name, b.state_desc from sys.database_principals a inner join sys.database_permissions b on a.principal_id = b.grantee_principal_id left join sys.all_objects o on b.major_id = o.object_id left join sys.all_columns c on (b.major_id = c.object_id and b.minor_id = c.column_id) where a.name = 'public' */
Object-Level Permissions
注意:如果对象的权限是通过role衍生的,而不是直接分配给user或者role,那么并不会被列出来。试想sysadmin 的角色,难道要列出所有数据库的所有对象吗?
[b]三. 查看自己的权限[/b]
1. 有没有登录权限
登录失败并不一定是没权限,还是找别人来检查自己账号的登录权限吧;
2. 有没有数据库访问权限
--列出所有可访问的数据库 SELECT * FROM sys.databases WHERE HAS_DBACCESS(name) = 1
3. 有没有对象访问权限
用上面提到HAS_PERMS_BY_NAME函数,它可以检查当前账号的各种权限;
SELECT HAS_PERMS_BY_NAME('test_sp', 'Object' , 'Execute') SELECT HAS_PERMS_BY_NAME('test', 'Database' , 'Execute')
4. 有哪些权限
--实例级权限 SELECT * FROM fn_my_permissions(NULL, 'SERVER'); --数据库级权限 SELECT * FROM fn_my_permissions ('DBA', 'DATABASE'); --对象权限,只能一个个对象检查,不能一次返回所有对象权限,和HAS_PERMS_BY_NAME类似 SELECT * FROM fn_my_permissions ('test_grant', 'OBJECT');
用于检查自己权限的方法,同样也可以检查其他账号,用EXECUTE AS切换账号即可。
相关文章推荐
- 数据库规范
- Oracle多行函数/组函数
- Oracle Study之--Oracle 11g RAC故障(Failed to create or upgrade OLR)
- StackExchange.Redis 使用 - 事件(五)
- Oracle Study之--Oracle 11g RAC故障(Failed to create or upgrade OLR)
- redis的备份
- 数据库(关系型)设计三大范式
- mysql多实例添加
- redis安装、配置、命令
- SDE ST_Geometry SQL st_intersects查询很慢的解决方法
- select into from与insert into select区别详解,sql语句复制表
- SQL优化
- oracle完整卸载,四步曲
- Mysql ——1045-Access denied for user 'root'@'localhost'(using password:YES)
- sqlServer 取每组的前几条数据
- spring集成redis cluster
- mysql命令行查看表结构,字段等信息 [mysql]
- nodejs+socketio+redis 简单消息推送实例(一)
- sql
- 【SQLite关系型数据库】SQLite语法