在SQL Server数据库中,登录账号分类如下:

(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

 

. 有没有权限

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;

 

. 有哪些权限

权限可以直接分配给账号,也可以分配给账号所属的role,所以要把账号自身权限、所属role权限合并才是最终的账号权限。

Windows账号权限还可以通过用户组分配,所以还要检查这个Windows账号有没有属于某个用户组,如果有还需要加上这个用户组的权限;

下面的脚本,仅检查单个用户/用户组权限。

1. 实例级的权限

use master
GO
declare @svr_principal_name varchar(1024)
set @svr_principal_name = 'test_login'

declare @svr_principal_id int
select @svr_principal_id = principal_id 
from sys.server_principals p
where p.name = @svr_principal_name

if OBJECT_ID('tempdb..#tmp_svr_role','U') is not null
    drop table #tmp_svr_role;
create table #tmp_svr_role
(
member_principal_id     int,
member_principal_name   varchar(512),
role_principal_id       int, 
role_principal_name     varchar(512)
)

--获取登录账号的所有server role, 从sql server 2012开始,server role可以自定义,成员仅可为fixed server role
;with tmp
as
(
select * from sys.server_role_members 
where member_principal_id = @svr_principal_id
union all
select rm.* from sys.server_role_members rm
inner join tmp 
on rm.member_principal_id = tmp.role_principal_id
)
insert into #tmp_svr_role 
select a.member_principal_id, b.name,
       a.role_principal_id, c.name
 from tmp a
inner join sys.server_principals b
on a.member_principal_id = b.principal_id
inner join sys.server_principals c
on a.role_principal_id = c.principal_id

--登录账号自身权限, sys.server_permissions不包含fixed server role权限,同时手动排除掉public权限
select a.principal_id as member_principal_id, a.name as member_principal_name,
       null as role_principal_id, null as role_principal_name,
       b.permission_name, b.state_desc
from sys.server_principals a
inner join sys.server_permissions b
on a.principal_id = b.grantee_principal_id
where a.principal_id = @svr_principal_id
and b.permission_name <> 'CONNECT SQL'
union all
--server role权限,包含fixed server role和自定义的server role
select a.member_principal_id, a.member_principal_name,
       a.role_principal_id, a.role_principal_name,
       isnull(b.permission_name,'Fixed Server-Level Role: '+role_principal_name) as permission_name, isnull(b.state_desc,'GRANT') as state_desc
from #tmp_svr_role a
left join sys.database_permissions b
on a.role_principal_id = b.grantee_principal_id
union all
--public server role权限,不可以取消public权限,它是每个登录账号的最小权限,仅可连接数据库实例
select @svr_principal_id as member_principal_id,@svr_principal_name as member_principal_name,
       principal_id as role_principal_id, name as role_principal_name, 
       'CONNECT SQL' as permission_name, 'GRANT' as state_desc
from sys.server_principals
where name = 'public'
Instance-Level Permissions

相关文章: