SELECT sp.name AS login_name, sr.name AS server_role
FROM sys.server_role_members rm
JOIN sys.server_principals sr ON rm.role_principal_id = sr.principal_id
JOIN sys.server_principals sp ON rm.member_principal_id = sp.principal_id
WHERE sp.name = N'aoi'ORDERBY sr.name;
2) 在 mes 库里:确认 aoi 映射成哪个 数据库用户(非常关键)
USE mes;
GO
SELECT
dp.name AS db_user,
dp.type_desc,
dp.authentication_type_desc
FROM sys.database_principals dp
WHERE dp.sid = SUSER_SID(N'aoi')OR dp.name = N'aoi';
你要记下查到的 db_user 名称(有时不叫 aoi)。下面我用 @dbuser 变量自动取出。
3) 检查是否被映射成 dbo / 是否是 db_owner
3.1 是否 dbo(或等价)
USE mes;
GO
DECLARE@dbuser sysname =(SELECTTOP(1) name
FROM sys.database_principals
WHERE sid = SUSER_SID(N'aoi')ORDERBYCASEWHEN name = N'dbo'THEN0ELSE1END, name
);SELECT@dbuserAS mapped_db_user;-- 是否为 db_ownerSELECT IS_ROLEMEMBER(N'db_owner',@dbuser)AS is_db_owner;-- 数据库所有者是谁(若 aoi 变成 owner 也会很危险)SELECT SUSER_SNAME(owner_sid)AS database_owner
FROM sys.databasesWHERE name = N'mes';
4) 列出 aoi 在 mes 的 数据库角色成员关系(常见“全权限”的根源)
USE mes;
GO
DECLARE@dbuser sysname =(SELECTTOP(1) name
FROM sys.database_principals
WHERE sid = SUSER_SID(N'aoi'));SELECT
m.name AS user_name,
r.name AS db_role
FROM sys.database_role_members drm
JOIN sys.database_principals r ON drm.role_principal_id = r.principal_id
JOIN sys.database_principals m ON drm.member_principal_id = m.principal_id
WHERE m.name =@dbuserORDERBY r.name;
USE mes;
GO
DECLARE@dbuser sysname =(SELECTTOP(1) name
FROM sys.database_principals
WHERE sid = SUSER_SID(N'aoi'));SELECT
dp.name AS user_name,
perm.state_desc,
perm.permission_name,
perm.class_desc
FROM sys.database_permissions perm
JOIN sys.database_principals dp ON perm.grantee_principal_id = dp.principal_id
WHERE dp.name =@dbuserAND perm.class_desc ='DATABASE'ORDERBY perm.permission_name;
USE mes;
GO
DECLARE@dbuser sysname =(SELECTTOP(1) name
FROM sys.database_principals
WHERE sid = SUSER_SID(N'aoi'));SELECT
dp.name AS user_name,
perm.state_desc,
perm.permission_name,
s.name AS schema_name
FROM sys.database_permissions perm
JOIN sys.database_principals dp ON perm.grantee_principal_id = dp.principal_id
JOIN sys.schemas s ON perm.major_id = s.schema_id
WHERE dp.name =@dbuserAND perm.class_desc ='SCHEMA'ORDERBY s.name, perm.permission_name;
如果你看到对 dbo 或某个业务 schema 有 CONTROL/ALTER 或 INSERT/UPDATE/DELETE,那基本就解释了“能改 MES 所有表”。
6) 查对象级权限:他到底被授了哪些表/视图/存储过程权限
USE mes;
GO
DECLARE@dbuser sysname =(SELECTTOP(1) name
FROM sys.database_principals
WHERE sid = SUSER_SID(N'aoi'));SELECT
dp.name AS user_name,
perm.state_desc,
perm.permission_name,
sch.name AS schema_name,
obj.name AS object_name,
obj.type_desc
FROM sys.database_permissions perm
JOIN sys.database_principals dp ON perm.grantee_principal_id = dp.principal_id
JOIN sys.objects obj ON perm.major_id = obj.object_id
JOIN sys.schemas sch ON obj.schema_id = sch.schema_id
WHERE dp.name =@dbuserORDERBY sch.name, obj.name, perm.permission_name;
7) 从“有效权限”角度验证:aoi 实际上能做什么(含角色继承)
USE mes;
GO
DECLARE@dbuser sysname =(SELECTTOP(1) name
FROM sys.database_principals
WHERE sid = SUSER_SID(N'aoi'));EXECUTEASUSER=@dbuser;SELECT*FROM fn_my_permissions(NULL,'DATABASE');
REVERT;
如果这里出现 ALTER ANY SCHEMA / CONTROL / ALTER / INSERT / UPDATE / DELETE 等,就说明有效权限已超出只读。