What occurs when the Security Group Policy CSE encounters a null DACL

Mike here. The Group Policy security client side extension can distribute security descriptors on files and registry keys. This extension is difficult to troubleshoot because it is considerably durable when it comes to failures. In most situations, it completes processing, but not without leaving behind the ever popular SCECLI 1202 event.

Event Type: Warning
Event Source: SceCli
Event Category: None
Event ID: 1202
Date: 21/09/1999
Time: 18:15:14
User: N/A
Computer: MachineName
Description:
Security policies are propagated with warning. 0x4b8 : An extended error occurred. Please look for more details in TroubleShooting section in Security Help.

You can start your troubleshooting by following Microsoft Knowledge base article 324383 Troubleshooting SCECLI 1202 Events. Unfortunately, the return code 0x4b8 is ambiguous because it serves as generic alert of a nondeterministic problem-- it means something happened; but what happened was not catastrophic. Therefore, the security extension keeps processing,

  • NOTE: The knowledge base article uses the command secedit /refreshpolicy machine_policy /enforce. For Windows XP and later use the command gpupdate /force.

Security extension processing has many facets. Using the previously mentioned knowledge base article should help you understand the general area within security processing that is failing. However, it's not enough evidence to confirm Professor Plum, did it in the library with the candlestick. But you should be able to determine the misbehaving portion of security processing from the winlogon.log. Scan the log file for the Configure File Security... section. It may look like:

----Configure File Security...

Configure c:\.

File Security configuration was completed with one or more errors.

If you suspect your file system security settings as the culprit, then you may want to use Process Monitor to help further determine where in the failure occurs. It's difficult to provide prescriptive guidance when there are many reasons for the resulting error. However, one scenario where we see this problem is in the case of a nested file or folder containing a null discretionary access control list (DACL).

NOTE: You can read more about the differences between null and empty discretionary access control list by reading the Null and Empty DACLs ASKDS blog post.

The scenario we encounter usually involves using the security policy extension to assign file permissions to a particular folder. Files and folders residing beneath the targeted folder inherit the permissions that are assigned to the targeted folder, unless that file or folder specifically blocks inheritance. If one of the underlying files or folders beneath the targeted folder contains a null DACL, then the security extension halts processing the remainder of file system security. Furthermore, an entry appears in the winlogon.log stating the configuration completed with one or more errors and, an event with the event ID 1202 appears is recorded to the event log. The return code reported in the event log is 0x4b8. Lastly, the winlogon.log file does not contain information on the file or folder responsible for stopping the process. The parent folder is the only item listed in the log. This means that one or more files or folder beneath the folder listed in the log file is responsible for halting security processing. The problem now is how to identify those files or folders. But, let's explain why security processing halts.

Why a null DACL halts file security Group Policy processing

I previously mentioned that permissions we assign to folders through security policy processing propagate to all files and folders hosted within the targeted folder. Propagating security is known as inheritance, where a file or folder beneath a folder receives subset of the permissions from the containing folder. Windows must calculate the subset of permissions to apply to files and folders beneath the targeted folder. Windows derives these permissions by combining permission from the targeted folder and the file or folder beneath the targeted folder. Permission from the targeted folder are known as inherited permissions. Permissions on the file or folder residing in the targeted folder are explicit permissions. The problem with security processing occurs when the file or folder residing in the targeted folder contains a null DACL. Explicitly, this file or folder does not have any permissions. So Windows cannot determine how to propagate inherited permissions to the object because the object itself does not actually have permissions ( see ASKDS blog post Null and Empty DACLs).

More on inheritance

The security extension must compute inheritance. Computing inheritance, is essentially asking the security extension to figure out how to add permissions from the parent object to the a child object that does not have room to store permissions. This would require the security extension to make arbitrary decision on intent. Is the null DACL on purpose? When does the extension observe the null DACL and when does it not? These are a few reasons why the security extension halts permission processing when it attempts to propagate inherited permissions after encountering a null DACL; it is not clear what the resulting permissions should be. Therefore, the security extension halts file security processing and moves forward with the next phase of Group Policy security processing. The recorded event is a warning, not an error. It is a warning because Group Policy security processing processed as a whole-- meaning none of the events that occur were catastrophic to the entire processing phase. However, one or more subcomponents did experience errors.

What to do

Detecting a null DACL is challenging. The Windows ACL editor interpret a null DACL for you; so your unaware if the DACL is null, or Everyone has Full Control. Windows includes CACLS.EXE, which reports if permissions are not set. This is an effective way to determine a null DACL exists but, you must have an idea of the file or folder containing the null DACL.

image

Identifying the a nested file or folder with a null DACL within a deep folder structure is difficult. Manually investigating these files or folders is not practical. Fortunately, ADSI provides a security descriptor interface we can use through scripting to recursively search folders, sub-folders, and files that may have a null DACL. Below is a sample script that can be copied and pasted into a text document.

'==========================================================================
'
' VBScript Source File
'
' NAME: CheckNullDacl.vbs
'
' AUTHOR: Mike Stephens , Microsoft Corporation
' DATE : 7/15/2003
'
' COMMENT:
'
'==========================================================================
' Microsoft provides programming examples for illustration only, without warranty either expressed or
' implied, including, but not limited to, the implied warranties of merchantability and/or fitness for a
' particular purpose. This sample assumes that you are familiar with the programming language being
' demonstrated and the tools used to create and debug procedures. Microsoft support professionals
' can help explain the functionality of a particular procedure, but they will not modify these examples
' to provide added functionality or construct procedures to meet your specific needs.
' =============================================================================

Option Explicit
Const ADS_PATH_FILE = 1
Const ADS_SD_FORMAT_IID = 1
Const SE_DACL_PRESENT = &h4
Const Dbg = False

Dim oArgs : Set oArgs = WScript.Arguments

If Not (oArgs.Count >= 1) Then
        WScript.Quit(0)
End If

WScript.Echo VbCrLf & "Recursivly searching " & oArgs.Unnamed(0) & " for NULL DACLs..." & vbCr

SearchSDsInFolder oArgs.Unnamed(0)

WScript.Echo VbCrLf & "-=[Complete]=-" & VbCrLf

WScript.Quit(0)

Sub IsNullDacl(fileArg, bFolder)
        Dim fso : Set fso = CreateObject("Scripting.FileSystemObject")
        Dim sdUtil : Set sdUtil = CreateObject("ADsSecurityUtility")
        Dim sd : Set sd = CreateObject("SecurityDescriptor")
        Dim dacl        

        Dim sdControl, sdObject, DaclAceCount

        If(bFolder) = False Then
                If(fso.FileExists(fileArg)) = False Then
                        Exit Sub
                Else
                        Set sdObject = fso.GetFile(fileArg)
                End If
        Else
                If(fso.FolderExists(fileArg)) = False Then
                        Exit Sub
                Else
                        Set sdObject = fso.GetFolder(fileArg)
                End If
        End If

        Set sd = sdUtil.GetSecurityDescriptor( sdObject.Path, ADS_PATH_FILE, ADS_SD_FORMAT_IID)       

        ' Get the SD Control
        sdControl = sd.Control               

        ' Get the SD DACL
        Set dacl = sd.DiscretionaryAcl
        On Error Resume Next
                DaclAceCount = dacl.AceCount
                If Err.Number = 424 Then
                        DaclAceCount = –1
                        Err.Clear
                End If
        On Error GoTo 0

        If(sdControl And SE_DACL_PRESENT <> SE_DACL_PRESENT) Then
                WScript.Echo "- Null DACL detected on " & cStr(sdObject.Path) & "."
                Exit Sub
        ElseIf(DaclAceCount = -1) Then
                WScript.Echo "- Null DACL detected on " & cStr(sdObject.Path) & "."
                Exit Sub
        Else
                DebugPrint "Processed " & cStr(sdObject.Path)
        End If
End Sub

Sub SearchSDsInFolder( folderArg)
        Dim fso : Set fso = CreateObject("Scripting.FileSystemObject")
        Dim flder, folder, folderCollection
        Dim file, fileCollection

        Set flder = fso.GetFolder(folderArg)

        If(flder.SubFolders.Count > 0) Then
                Set folderCollection = flder.SubFolders   
                For Each folder In folderCollection
                        SearchSDsInFolder(folder)
        Next
        End If

        IsNullDacl flder.Path, true

        Set fileCollection = flder.Files
        For Each file In fileCollection
                Dim f : Set f = fso.GetFile(file)
                IsNullDacl file.Path, False
        Next
End Sub

Sub DebugPrint( text)
        If( Dbg = True) Then
                WScript.Echo text & vbCr
        End If
End Sub  

Use cscript.exe to start the script. Provide a single argument when starting the script. This argument is the folder at which the search for null DACLs begins. The search is recursive; therefore, it searches all nested folders and files. Files or folders identified as having a null DACL are printed to the screen.

image

Most null DACL scenarios identify only one or two files (or folders) containing a null DACL. You can change a null DACL by using the ACL editor, ICACLS, CACLs, or other permission utilities. A large quantity of files or folder containing null DALCs may require a scripted solution using the previous mentioned utilities.

- Mike “#14” Stephens

checkNullDacl.txt