VBScript: read NTFS permissions (full control, read, change)

Using VBScript it can be pretty difficult to accurately read the permission ACL from a file or folder on an NTFS environment. Most solutions use XCACLS.EXE as command line tool to read the ACL and then parse the output using VBScript. I rather use the ADsSecurity object to get the actual “GetSecurityDescriptor” from the file or folder. Using this object, you can read each ACE entry from the ACL and translate that to readable output. This script combines the AccessMask from the ACE’s and translates that to either READ, FULL CONTROL or CHANGE. I got this script in a much larger form from another website, then modified it to be a lot shorter and only output the ACL in a specific form.

strInput = wscript.arguments(0)
strOutput = wscript.arguments(1)

const ADS_ACEFLAG_UNKNOWN = &h1
const ADS_ACEFLAG_INHERIT_ACE = &h2
const ADS_ACEFLAG_NO_PROPAGATE_INHERIT_ACE = &h4
const ADS_ACEFLAG_INHERIT_ONLY_ACE = &h8
const ADS_ACEFLAG_INHERITED_ACE = &h10
const ADS_ACEFLAG_VALID_INHERIT_FLAGS = &h1f
const ADS_ACEFLAG_SUCCESSFUL_ACCESS = &h40
const ADS_ACEFLAG_FAILED_ACCESS= &h80
const ADS_ACETYPE_ACCESS_ALLOWED = 0
const ADS_ACETYPE_ACCESS_DENIED = &h1
const ADS_ACETYPE_SYSTEM_AUDIT = &h2
const ADS_ACETYPE_ACCESS_ALLOWED_OBJECT= &h5
const ADS_ACETYPE_ACCESS_DENIED_OBJECT = &h6
const ADS_ACETYPE_SYSTEM_AUDIT_OBJECT = &h7

const FILE_READ_DATA = &h1
const FILE_LIST_DIRECTORY = &h1
const FILE_WRITE_DATA = &h2
const FILE_ADD_FILE = &h2
const FILE_APPEND_DATA = &h4
const FILE_ADD_SUBDIRECTORY = &h4
const FILE_READ_EA = &h8
const FILE_WRITE_EA= &h10
const FILE_EXECUTE = &h20
const FILE_TRAVERSE = &h20
const FILE_DELETE_CHILD = &h40
const FILE_READ_ATTRIBUTES = &h80
const FILE_WRITE_ATTRIBUTES= &h100
const DELETE = &h10000
const READ_CONTROL = &h20000
const WRITE_DAC = &h40000
const WRITE_OWNER = &h80000
const SYNCHRONIZE = &h100000

const ADS_RIGHT_GENERIC_ALL = &h10000000
const ADS_RIGHT_GENERIC_EXECUTE = &h20000000
const ADS_RIGHT_GENERIC_WRITE = &h40000000
const ADS_RIGHT_GENERIC_READ = &h80000000

Dim adsFILE_FULL
Dim adsFOLDER_FULL
Dim adsFILE_CHANGE
Dim adsFOLDER_CHANGE
Dim adsFILE_READ
Dim adsFOLDER_READ
Dim adsFILE_NOACCESS
Dim adsFOLDER_NOACCESS

adsFILE_FULL= FILE_READ_DATA Or FILE_WRITE_DATA Or FILE_APPEND_DATA Or _
FILE_READ_EA Or FILE_WRITE_EA Or FILE_EXECUTE Or FILE_DELETE_CHILD Or _
FILE_READ_ATTRIBUTES Or FILE_WRITE_ATTRIBUTES Or DELETE Or _
READ_CONTROL Or WRITE_DAC Or WRITE_OWNER Or SYNCHRONIZE
adsFOLDER_FULL = FILE_LIST_DIRECTORY Or FILE_ADD_FILE Or FILE_ADD_SUBDIRECTORY Or _
FILE_READ_EA Or FILE_WRITE_EA Or FILE_TRAVERSE Or FILE_DELETE_CHILD Or _
FILE_READ_ATTRIBUTES Or FILE_WRITE_ATTRIBUTES Or DELETE Or _
READ_CONTROL Or WRITE_DAC Or WRITE_OWNER Or SYNCHRONIZE
adsFILE_CHANGE = FILE_READ_DATA Or FILE_WRITE_DATA Or FILE_APPEND_DATA Or _
FILE_READ_EA Or FILE_WRITE_EA Or FILE_EXECUTE Or _
FILE_READ_ATTRIBUTES Or FILE_WRITE_ATTRIBUTES Or DELETE Or _
READ_CONTROL Or SYNCHRONIZE
adsFOLDER_CHANGE= FILE_LIST_DIRECTORY Or FILE_ADD_FILE Or FILE_ADD_SUBDIRECTORY Or _
FILE_READ_EA Or FILE_WRITE_EA Or FILE_TRAVERSE Or _
FILE_READ_ATTRIBUTES Or FILE_WRITE_ATTRIBUTES Or DELETE Or _
READ_CONTROL Or SYNCHRONIZE
adsFILE_READ = FILE_READ_DATA Or FILE_READ_EA Or FILE_EXECUTE Or _
FILE_READ_ATTRIBUTES Or READ_CONTROL Or SYNCHRONIZE
adsFOLDER_READ= FILE_LIST_DIRECTORY Or FILE_READ_EA Or FILE_TRAVERSE Or _
FILE_READ_ATTRIBUTES Or READ_CONTROL Or SYNCHRONIZE
adsFILE_NOACCESS = FILE_READ_DATA Or FILE_WRITE_DATA Or FILE_APPEND_DATA Or _
FILE_READ_EA Or FILE_WRITE_EA Or FILE_EXECUTE Or FILE_DELETE_CHILD Or _
FILE_READ_ATTRIBUTES Or FILE_WRITE_ATTRIBUTES Or DELETE Or _
READ_CONTROL Or WRITE_DAC Or WRITE_OWNER
adsFOLDER_NOACCESS = FILE_LIST_DIRECTORY Or FILE_ADD_FILE Or FILE_ADD_SUBDIRECTORY Or _
FILE_READ_EA Or FILE_WRITE_EA Or FILE_TRAVERSE Or FILE_DELETE_CHILD Or _
FILE_READ_ATTRIBUTES Or FILE_WRITE_ATTRIBUTES Or DELETE Or _
READ_CONTROL Or WRITE_DAC Or WRITE_OWNER

Dim hAccessMask
Dim ACLMode
Dim oADSSecurity
Set oADSSecurity = CreateObject(“ADsSecurity”)

set fso = CreateObject(“Scripting.FileSystemObject”)
set csvOutput = fso.CreateTextFile(strOutput, true)

set oTargetSD = oADsSecurity.GetSecurityDescriptor(“FILE://” & Cstr(strInput))
set oDACL = oTargetSD.DiscretionaryACL

If fso.FileExists(strInput) Then
ACLMode = 0
ElseIf fso.FolderExists(strInput) Then
ACLMode = 1
Else
WScript.Quit
End If

For Each oACE in oDACL
hAccessMask = 0
csvOutput.Write oACE.Trustee & “;”
Select Case oACE.AceType
Case ADS_ACETYPE_ACCESS_ALLOWED
csvOutput.Write”Allow;”
Case ADS_ACETYPE_ACCESS_DENIED
csvOutput.Write “Denied;”
Case ADS_ACETYPE_ACCESS_ALLOWED_OBJECT
csvOutput.Write”Allow;”
Case ADS_ACETYPE_ACCESS_DENIED_OBJECT
csvOutput.Write “Denied;”
End Select

if ACLMode = 0 then

If (oACE.AccessMask AND FILE_READ_DATA) Then hAccessMask = hAccessMask + FILE_READ_DATA
If (oACE.AccessMask AND FILE_WRITE_DATA) Then hAccessMask = hAccessMask + FILE_WRITE_DATA
If (oACE.AccessMask AND FILE_APPEND_DATA) Then hAccessMask = hAccessMask + FILE_APPEND_DATA
If (oACE.AccessMask AND FILE_READ_EA) Then hAccessMask = hAccessMask + FILE_READ_EA
If (oACE.AccessMask AND FILE_WRITE_EA) Then hAccessMask = hAccessMask + FILE_WRITE_EA
If (oACE.AccessMask AND FILE_EXECUTE) Then hAccessMask = hAccessMask + FILE_EXECUTE
If (oACE.AccessMask AND FILE_DELETE_CHILD) Then hAccessMask = hAccessMask + FILE_DELETE_CHILD
If (oACE.AccessMask AND FILE_READ_ATTRIBUTES) Then hAccessMask = hAccessMask + FILE_READ_ATTRIBUTES
If (oACE.AccessMask AND FILE_WRITE_ATTRIBUTES) Then hAccessMask = hAccessMask + FILE_WRITE_ATTRIBUTES
If (oACE.AccessMask AND DELETE) Then hAccessMask = hAccessMask + DELETE
If (oACE.AccessMask AND READ_CONTROL) Then hAccessMask = hAccessMask + READ_CONTROL
If (oACE.AccessMask AND WRITE_DAC) Then hAccessMask = hAccessMask + WRITE_DAC
If (oACE.AccessMask AND WRITE_OWNER) Then hAccessMask = hAccessMask + WRITE_OWNER
If (oACE.AccessMask AND SYNCHRONIZE) Then hAccessMask = hAccessMask + SYNCHRONIZE
end if

if ACLMode = 1 then

If (oACE.AccessMask AND FILE_LIST_DIRECTORY) Then hAccessMask = hAccessMask + FILE_LIST_DIRECTORY
If (oACE.AccessMask AND FILE_ADD_FILE) Then hAccessMask = hAccessMask + FILE_ADD_FILE
If (oACE.AccessMask AND FILE_ADD_SUBDIRECTORY) Then hAccessMask = hAccessMask + FILE_ADD_SUBDIRECTORY
If (oACE.AccessMask AND FILE_READ_EA) Then hAccessMask = hAccessMask + FILE_READ_EA
If (oACE.AccessMask AND FILE_WRITE_EA) Then hAccessMask = hAccessMask + FILE_WRITE_EA
If (oACE.AccessMask AND FILE_TRAVERSE) Then hAccessMask = hAccessMask + FILE_TRAVERSE
If (oACE.AccessMask AND FILE_DELETE_CHILD) ThenhAccessMask = hAccessMask + FILE_DELETE_CHILD
If (oACE.AccessMask AND FILE_READ_ATTRIBUTES) Then hAccessMask = hAccessMask + FILE_READ_ATTRIBUTES
If (oACE.AccessMask AND FILE_WRITE_ATTRIBUTES) Then hAccessMask = hAccessMask + FILE_WRITE_ATTRIBUTES
If (oACE.AccessMask AND DELETE) Then hAccessMask = hAccessMask + DELETE
If (oACE.AccessMask AND READ_CONTROL) Then hAccessMask = hAccessMask + READ_CONTROL
If (oACE.AccessMask AND WRITE_DAC) Then hAccessMask = hAccessMask + WRITE_DAC
If (oACE.AccessMask AND WRITE_OWNER) Then hAccessMask = hAccessMask + WRITE_OWNER
If (oACE.AccessMask AND SYNCHRONIZE) Then hAccessMask = hAccessMask + SYNCHRONIZE
end if

Select Case hAccessMask
Case adsFILE_FULL
csvOutput.WriteLine “FULL CONTROL;”
Case adsFOLDER_FULL
csvOutput.WriteLine “FULL CONTROL;”
Case adsFILE_CHANGE
csvOutput.WriteLine “CHANGE;”
Case adsFOLDER_CHANGE
csvOutput.WriteLine “CHANGE;”
Case adsFILE_READ
csvOutput.WriteLine “READ;”
Case adsFOLDER_READ
csvOutput.WriteLine “READ;”
Case adsFILE_NOACCESS
csvOutput.WriteLine “NO ACCESS;”
Case adsFOLDER_NOACCESS
csvOutput.WriteLine “NO ACCESS;”
Case Else
csvOutput.WriteLine oACE.AccessMask & “;”
End Select
Next

Geschreven door:

Arnout van der Vorst

Arnout van der Vorst is Identity Management Architect bij Tools4ever en al ruim 10 jaar in dienst. Arnout legt zich als Architect toe op het bedenken en ontwikkelen van nieuwe features, oplossingen en diensten van Tools4ever die aansluiten op de vraag uit de markt. Arnout studeerde Hogere Informatica aan de Hogeschool van Utrecht.
Terug