Re: Scripting NTFS Permissions by maxv
maxv
Mon Aug 11 07:51:59 CDT 2003
ADsSecurity.dll or ADsSecurityUtility from XP or Win2k3.
ADsSecurity.dll will not propagate inheritable ACEs to sub folders. You would need to create a simple wrapper for GetNamedSecurityINfo and
SetNamedSecurityInfo. You are respnsible for reordering the DACL.
ADsSecurityUtility will propagate inheritable ACEs and will properly order the DACL.
Below is a simple script to set full control permissions on an NTFS file using ADsSecurity.dll. If you want to use ADsSecurityUtility,just yell back and I'll post
another script.
Sincerely,
Max Vaughn [MS]
Microsoft Developer Support
Disclaimer: This posting is provided "AS IS" with no warranties, and confers no rights. You assume all risk for your use.
'
' Define some constants:
'
'
' Define a ADS_RIGHTS_ENUM constants constants:
'
const ADS_RIGHT_DELETE = &h10000
const ADS_RIGHT_READ_CONTROL = &h20000
const ADS_RIGHT_WRITE_DAC = &h40000
const ADS_RIGHT_WRITE_OWNER = &h80000
const ADS_RIGHT_SYNCHRONIZE = &h100000
const ADS_RIGHT_ACCESS_SYSTEM_SECURITY = &h1000000
const ADS_RIGHT_GENERIC_READ = &h80000000
const ADS_RIGHT_GENERIC_WRITE = &h40000000
const ADS_RIGHT_GENERIC_EXECUTE = &h20000000
const ADS_RIGHT_GENERIC_ALL = &h10000000
const ADS_RIGHT_DS_CREATE_CHILD = &h1
const ADS_RIGHT_DS_DELETE_CHILD = &h2
const ADS_RIGHT_ACTRL_DS_LIST = &h4
const ADS_RIGHT_DS_SELF = &h8
const ADS_RIGHT_DS_READ_PROP = &h10
const ADS_RIGHT_DS_WRITE_PROP = &h20
const ADS_RIGHT_DS_DELETE_TREE = &h40
const ADS_RIGHT_DS_LIST_OBJECT = &h80
const ADS_RIGHT_DS_CONTROL_ACCESS = &h100
'++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
'
' Ace Type definitions
'
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
'++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
'
' Ace Flag Constants
'
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
'++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
' Flags constants for AD objects
'
const ADS_FLAG_OBJECT_TYPE_PRESENT = &h1
const ADS_FLAG_INHERITED_OBJECT_TYPE_PRESENT = &h2
'++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
'
' From WinNT.h
'------------------------------------------------------------------------------
'++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
' File Specific Access Rights
'
Const DELETE = &h00010000
Const READ_CONTROL = &h00020000
Const WRITE_DAC = &h00040000
Const WRITE_OWNER = &h00080000
Const SYNCHRONIZE = &h00100000
Const STANDARD_RIGHTS_REQUIRED = &h000F0000
Dim STANDARD_RIGHTS_READ : STANDARD_RIGHTS_READ = READ_CONTROL
Dim STANDARD_RIGHTS_WRITE : STANDARD_RIGHTS_WRITE = READ_CONTROL
Dim STANDARD_RIGHTS_EXECUTE: STANDARD_RIGHTS_EXECUTE = READ_CONTROL
Const STANDARD_RIGHTS_ALL = &h001F0000
Const SPECIFIC_RIGHTS_ALL = &h0000FFFF
'
' AccessSystemAcl access type
'
Const ACCESS_SYSTEM_SECURITY = &h01000000
'
' MaximumAllowed access type
'
Const MAXIMUM_ALLOWED = &h02000000
'
' These are the generic rights.
'
Const GENERIC_READ = &h80000000
Const GENERIC_WRITE = &h40000000
Const GENERIC_EXECUTE = &h20000000
Const GENERIC_ALL = &h10000000
'
' AccessMask constants for FILE ACEs
'
Const FILE_READ_DATA = &h0001 ' file & pipe
Const FILE_LIST_DIRECTORY = &h0001 ' directory
Const FILE_WRITE_DATA = &h0002 ' file & pipe
Const FILE_ADD_FILE = &h0002 ' directory
Const FILE_APPEND_DATA = &h0004 ' file
Const FILE_ADD_SUBDIRECTORY = &h0004 ' directory
Const FILE_CREATE_PIPE_INSTANCE = &h0004 ' named pipe
Const FILE_READ_EA = &h0008 ' file & directory
Const FILE_WRITE_EA = &h0010 ' file & directory
Const FILE_EXECUTE = &h0020 ' file
Const FILE_TRAVERSE = &h0020 ' directory
Const FILE_DELETE_CHILD = &h0040 ' directory
Const FILE_READ_ATTRIBUTES = &h0080 ' all
Const FILE_WRITE_ATTRIBUTES = &h0100 ' all
Dim FILE_ALL_ACCESS : FILE_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED Or SYNCHRONIZE Or &h1FF
dim FILE_GENERIC_READ : FILE_GENERIC_READ = STANDARD_RIGHTS_READ Or _
FILE_READ_DATA Or _
FILE_READ_ATTRIBUTES Or _
FILE_READ_EA Or _
SYNCHRONIZE
dim FILE_GENERIC_WRITE : FILE_GENERIC_WRITE = STANDARD_RIGHTS_WRITE Or _
FILE_WRITE_DATA Or _
FILE_WRITE_ATTRIBUTES Or _
FILE_WRITE_EA Or _
FILE_APPEND_DATA Or _
SYNCHRONIZE
dim FILE_GENERIC_EXECUTE : FILE_GENERIC_EXECUTE = STANDARD_RIGHTS_EXECUTE Or _
FILE_READ_ATTRIBUTES Or _
FILE_EXECUTE Or _
SYNCHRONIZE
Const FILE_SHARE_READ = &h00000001
Const FILE_SHARE_WRITE = &h00000002
Const FILE_SHARE_DELETE = &h00000004
'
' AceFlags values for files
'
Const OBJECT_INHERIT_ACE = &H1
Const CONTAINER_INHERIT_ACE = &H2
Const NO_PROPAGATE_INHERIT_ACE = &H4
Const INHERIT_ONLY_ACE = &H8
Const INHERITED_ACE = &H10
'++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
'==========================================================================
' Sub to reorder an ACL
' Comments in the subroutine explain how the ACL should be ordered.
' The IADsAccessControlList::AddAce method makes not attempt to properly
' order the ACE being added.
'
Sub ReorderDacl( dacl )
'
' Initialize all of the new ACLs
'
' VBS methods of creating the ACL bins
'
Set newdacl = CreateObject("AccessControlList")
Set ImpDenyDacl = CreateObject("AccessControlList")
Set InheritedDacl = CreateObject("AccessControlList")
Set ImpAllowDacl = CreateObject("AccessControlList")
Set InhAllowDacl = CreateObject("AccessControlList")
Set ImpDenyObjectDacl = CreateObject("AccessControlList")
Set ImpAllowObjectDacl = CreateObject("AccessControlList")
'
' Sift the DACL into 5 bins:
' Inherited Aces
' Implicit Deny Aces
' Implicit Deny Object Aces
' Implicit Allow Aces
' Implicit Allow object aces
'
For Each ace In dacl
'
' Sort the orignal ACEs into thier appropriate
' ACLs
'
If ((ace.AceFlags And ADS_ACEFLAG_INHERITED_ACE) = ADS_ACEFLAG_INHERITED_ACE)Then
'
' Don't really care about the order of inherited aces. Since we are
' adding them to the top of a new list, when they are added back
' to the Dacl for the object, they will be in the same order as
' they were orginally. Just a positive side affect of adding items
' of a LIFO ( Last In First Out) type list.
'
InheritedDacl.AddAce ace
Else
'
' We have an Implicit ACE, lets put it the proper pool
'
Select Case ace.AceType
Case ADS_ACETYPE_ACCESS_ALLOWED
'
' We have an implicit allow ace
'
ImpAllowDacl.AddAce ace
Case ADS_ACETYPE_ACCESS_DENIED
'
' We have a implicit Deny ACE
'
ImpDenyDacl.AddAce ace
Case ADS_ACETYPE_ACCESS_ALLOWED_OBJECT
'
' We have an object allowed ace
' Does it apply to a property? or an Object?
'
impAllowObjectDacl.AddAce ace
Case ADS_ACETYPE_ACCESS_DENIED_OBJECT
'
' We have a object Deny ace
'
ImpDenyObjectDacl.AddAce ace
Case Else
'
' Missed a bin?
'
End Select
End If
Next
'
' Combine the ACEs in the proper order
' Implicit Deny
' Implicit Deny Object
' Implicit Allow
' Implicit Allow Object
' Inherited aces
'
' Implicit Deny
'
For Each ace In ImpDenyDacl
newdacl.AddAce ace
Next
'
' Implicit Deny Object
'
For Each ace In ImpDenyObjectDacl
newdacl.AddAce ace
Next
'
' Implicit Allow
'
For Each ace In ImpAllowDacl
newdacl.AddAce ace
Next
'
' Implicit Allow Object
'
For Each ace In impAllowObjectDacl
newdacl.AddAce ace
Next
'
' Inherited Aces
'
For Each ace In InheritedDacl
newdacl.AddAce ace
Next
'
' Clean up
'
Set InheritedDacl = Nothing
Set ImpAllowDacl = Nothing
Set ImpDenyObjectDacl = Nothing
Set ImpDenyDacl = Nothing
'
' Set the appropriate revision level
' for the DACL
'
newdacl.AclRevision = dacl.AclRevision
'
' Replace the Security Discriptor
'
Set dacl = nothing
Set dacl = newdacl
end Sub
'==========================================================================
'
'<<<<<<<<<<<<<<<<<<<<<<<<< Begin IADsSecurity Constants >>>>>>>>>>>>
'
' Supported on Win2k with ADsSecurity.dll registered on the client.
' NOTE: ADsSecurity.dll does not work properly on XP, use ADsSecurityUTility object
' instead.
'
'
'++++++++++++++++++ MAIN SCRIPT ++++++++++++++++++++++++++++++++++
'
Dim oAce ' variable for the new ACE
Dim oDacl ' variable for the DACL of the object
Dim oSD ' variable for the Security Descriptor of the object
Dim oADsSecurityUtility ' variable for the ADsSecurity object
'
' Create an ACE object
' and an IADsSecurity object
'
set oAce = CreateObject("AccessControlEntry")
Set oADsSecurityUtility = CreateObject("ADsSecurity")
'
' Retreive the Security Descriptor for the given NTFS File path
' Using ADsSecurity.dll
'
Set oSD = oADsSecurityUtility.GetSecurityDescriptor( "FILE://c:\testdir" )
'
' Retrieve the Discretionary ACL for the Key
'
Set oDACL = oSD.DiscretionaryACL
'
' Set the IADsAccessControlEntry::Trustee attribute
'
oAce.Trustee = "BR549\BrettH"
'
' Set the IADsAccessControlEntry::AccessMask attribute
'
oAce.AccessMask = FILE_GENERIC_READ Or _
FILE_GENERIC_WRITE Or _
FILE_GENERIC_EXECUTE Or _
DELETE
'
' Set the IADsAccessControlEntry::AceType attribute
'
oAce.AceType = ADS_ACETYPE_ACCESS_ALLOWED
'
' Set the IADsAccessControlEntry::AceFlags attribute
'
oAce.AceFlags = OBJECT_INHERIT_ACE Or _
CONTAINER_INHERIT_ACE
'
' Place the ACE on the DACL
'
oDacl.AddAce oAce
'
' Reorder the DACL and place it back
' onto the file
'
ReorderDacl oDacl
'
' Place the DACL back onto the SD
'
oSD.DiscretionaryACL = oDACL
oADsSecurityUtility.SetSecurityDescriptor oSD
'
' Clean up
'
Set oAce = Nothing
Set oDACL = Nothing
Set oSD = Nothing
Set oADsSecurityUtility = Nothing
WScript.Echo "<<<<<<<<<<<<< Done >>>>>>>>>>>>>>>>"