Category Archives: Security

List granted permissions in a database

USE ['<database_name, sysname, sample_database>'];
WITH CTE_LIST_GRANTED_SECURITY 
(
      UserName
    , UserType
    , DatabaseUserName
    , Role
    , PermissionType
    , PermissionState
    , ObjectType
    , ObjectName
    , ColumnName
)
AS
(
    SELECT  
        [UserName] = CASE princ.[type] 
                        WHEN 'S' THEN princ.[name]
                        WHEN 'U' THEN ulogin.[name] COLLATE Latin1_General_CI_AI
                     END,
        [UserType] = CASE princ.[type]
                        WHEN 'S' THEN 'SQL User'
                        WHEN 'U' THEN 'Windows User'
                     END,  
        [DatabaseUserName] = princ.[name],       
        [Role] = null,      
        [PermissionType] = perm.[permission_name],       
        [PermissionState] = perm.[state_desc],       
        [ObjectType] = obj.type_desc,--perm.[class_desc],       
        [ObjectName] = OBJECT_NAME(perm.major_id),
        [ColumnName] = col.[name]
    FROM sys.database_principals princ  
    LEFT JOIN sys.login_token ulogin on princ.[sid] = ulogin.[sid]
    LEFT JOIN sys.database_permissions perm ON perm.[grantee_principal_id] = princ.[principal_id]
    LEFT JOIN sys.columns col ON col.[object_id] = perm.major_id 
                        AND col.[column_id] = perm.[minor_id]
    LEFT JOIN sys.objects obj ON perm.[major_id] = obj.[object_id]
    WHERE 
        princ.[type] in ('S','U')
    UNION

    SELECT  
        [UserName] = CASE memberprinc.[type] 
                        WHEN 'S' THEN memberprinc.[name]
                        WHEN 'U' THEN ulogin.[name] COLLATE Latin1_General_CI_AI
                     END,
        [UserType] = CASE memberprinc.[type]
                        WHEN 'S' THEN 'SQL User'
                        WHEN 'U' THEN 'Windows User'
                     END, 
        [DatabaseUserName] = memberprinc.[name],   
        [Role] = roleprinc.[name],      
        [PermissionType] = perm.[permission_name],       
        [PermissionState] = perm.[state_desc],       
        [ObjectType] = obj.type_desc,--perm.[class_desc],   
        [ObjectName] = OBJECT_NAME(perm.major_id),
        [ColumnName] = col.[name]
    FROM  sys.database_role_members members
    JOIN sys.database_principals roleprinc ON roleprinc.[principal_id] = members.[role_principal_id]
    JOIN sys.database_principals memberprinc ON memberprinc.[principal_id] = members.[member_principal_id]
    LEFT JOIN sys.login_token ulogin on memberprinc.[sid] = ulogin.[sid]
    LEFT JOIN sys.database_permissions perm ON perm.[grantee_principal_id] = roleprinc.[principal_id]
    LEFT JOIN sys.columns col on col.[object_id] = perm.major_id 
                        AND col.[column_id] = perm.[minor_id]
    LEFT JOIN sys.objects obj ON perm.[major_id] = obj.[object_id]
    UNION

    SELECT  
        [UserName] = '{All Users}',
        [UserType] = '{All Users}', 
        [DatabaseUserName] = '{All Users}',       
        [Role] = roleprinc.[name],      
        [PermissionType] = perm.[permission_name],       
        [PermissionState] = perm.[state_desc],       
        [ObjectType] = obj.type_desc,--perm.[class_desc],  
        [ObjectName] = OBJECT_NAME(perm.major_id),
        [ColumnName] = col.[name]
    FROM sys.database_principals roleprinc
    LEFT JOIN sys.database_permissions perm ON perm.[grantee_principal_id] = roleprinc.[principal_id]
    LEFT JOIN sys.columns col on col.[object_id] = perm.major_id 
                        AND col.[column_id] = perm.[minor_id]                   
    INNER JOIN sys.objects obj ON obj.[object_id] = perm.[major_id]
    WHERE
        roleprinc.[type] = 'R' AND
        roleprinc.[name] = 'public' AND
        obj.is_ms_shipped = 0
)
SELECT
  UserName
, UserType
, DatabaseUserName
, Role
, PermissionType
, PermissionState
, ObjectType
, ObjectName
, ColumnName
FROM 
    CTE_LIST_GRANTED_SECURITY
ORDER BY
UserName,
UserType,
PermissionType,
PermissionState
GO

Check if policy is checked

SELECT  
NAME
,LOGINPROPERTY(name, 'BadPasswordCount') AS 'BadPasswordCount'
,LOGINPROPERTY(name, 'BadPasswordTime') AS 'BadPasswordTime'
,LOGINPROPERTY(name, 'DaysUntilExpiration') AS 'DaysUntilExpiration'
,LOGINPROPERTY(name, 'DefaultDatabase') AS 'DefaultDatabase'
,LOGINPROPERTY(name, 'DefaultLanguage') AS 'DefaultLanguage'
,LOGINPROPERTY(name, 'HistoryLength') AS 'HistoryLength'
,LOGINPROPERTY(name, 'IsExpired') AS 'IsExpired'
,LOGINPROPERTY(name, 'IsLocked') AS 'IsLocked'
,LOGINPROPERTY(name, 'IsMustChange') AS 'IsMustChange'
,LOGINPROPERTY(name, 'LockoutTime') AS 'LockoutTime'
,LOGINPROPERTY(name, 'PasswordHash') AS 'PasswordHash'
,LOGINPROPERTY(name, 'PasswordLastSetTime') AS 'PasswordLastSetTime'
,LOGINPROPERTY(name, 'PasswordHashAlgorithm') AS 'PasswordHashAlgorithm'
,is_expiration_checked  As 'is_expiration_checked'
FROM    sys.sql_logins
WHERE   is_policy_checked = 1

sp_AutoFixUsers

This stored procedure checks for orphaned users and fixces them.

use master
go
create procedure sp_AutoFixUsers
as
set nocount on
 
DECLARE @OrphanedUsers TABLE
(
  OrphandedUserId int identity(1,1) primary key,
  UserName sysname,
  UserSID  varbinary(85)
)
INSERT INTO @OrphanedUsers
EXEC sp_change_users_login 'report'
 
if not exists (select 1 from @OrphanedUsers)
begin
       print 'No orphaned users found in database '+quotename(db_name(db_id()))
end
 
DECLARE @LoginName sysname
 
DECLARE orphaned_cursor CURSOR LOCAL FORWARD_ONLY FAST_FORWARD FOR
SELECT UserName FROM @OrphanedUsers
 
OPEN orphaned_cursor  
FETCH NEXT FROM orphaned_cursor INTO @LoginName  
 
WHILE @@FETCH_STATUS = 0  
BEGIN  
       print char(10)+ 'Orphaned user ' + quotename(@LoginName)+' found'
       EXEC sp_change_users_login @Action = 'Auto_Fix' , @UserNamePattern = @LoginName
       print char(10)
    FETCH NEXT FROM orphaned_cursor INTO @LoginName
END  
 
CLOSE orphaned_cursor  
DEALLOCATE orphaned_cursor;

Because this stored procedure is created in the master database with the prefix sp_ it's registered as system stored procedure.  With this feature on it's possible to call this stored procedure from any database on the instance.

single database call example

use <YourDatabase>; exec sp_AutoFixUsers;

Run on every database in one single statement

exec sp_MsForEachDb 'use [?]; exec sp_AutoFixUsers;'