How To Use ADSI to Set Automatic Inheritance of File/Folder Permissions
This article was previously published under Q266461
File permissions that are set on files and folders using Active Directory Services Interface (ADSI) and the ADSI resource kit utility, ADsSecurity.DLL, do not automatically propagate down the subtree to the existing folders and files.
To accomplish automatic propagation of inheritable Access Control Entries (ACEs) using ADSI, you need to enumerate existing subfolders and files yourself and apply the inheritable ACEs. Alternatively, you can call the SetSecurityInfo or SetNamedSecurityInfo function directly instead of using ADSI.
The reason that you cannot use ADSI to set ACEs to propagate down to existing files and folders is because ADSSecurity.dll uses the low-level SetFileSecurity function to set the security descriptor on a folder. There is no flag that can be set by using SetFileSecurity to automatically propagate the ACEs down to existing files and folders. The SE_DACL_AUTO_INHERIT_REQ control flag will only set the SE_DACL_AUTO_INHERITED flag in the security descriptor that is associated with the folder.
Automatic propagation of inheritable ACEs is done only when using the high-level SetSecurityInfo or SetNamedSecurityInfo function. These functions propagate the inheritable ACEs (CONTAINER_INHERIT_ACE or OBJECT_INHERIT_ACE) set on a folder to all existing subfolders and files, as long as the child object's DACL is not SE_DACL_PROTECTED. This is done only in the high-level access control implementation by enumerating the subfolders as well as files, and applying all of the inheritable ACEs.
The following sample VB Script demonstrates how to enumerate folders and files and set file permissions using ADSI and ADsSecurity.DLL:
- Create a file called SetPerms.vbs and paste the following code:
'===================================================================='SetPerms.vbs'===================================================================='Variable DeclarationsDim sec Dim sd Dim Dacl Dim aceDim ace1Dim ace2Dim oSidDim sidHex'Option Explicit'Flags: Specifies Inheritanceconst ADS_ACEFLAG_INHERIT_ACE = &h2const ADS_ACEFLAG_NO_PROPAGATE_INHERIT_ACE = &h4const ADS_ACEFLAG_INHERIT_ONLY_ACE = &h8const ADS_ACEFLAG_INHERITED_ACE = &h10const ADS_ACEFLAG_VALID_INHERIT_FLAGS = &h1fconst ADS_ACEFLAG_SUCCESSFUL_ACCESS = &h40const ADS_ACEFLAG_FAILED_ACCESS = &h80'Permission Type: Allow or Denyconst ADS_ACETYPE_ACCESS_ALLOWED = &h0const ADS_ACETYPE_ACCESS_DENIED = &h1'Permissions: Read, Write, FullControlconst ADS_RIGHT_GENERIC_READ = &h80000000const ADS_RIGHT_GENERIC_WRITE = &h40000000const ADS_RIGHT_GENERIC_EXECUTE = &h20000000const ADS_RIGHT_GENERIC_ALL = &h10000000const ADS_SID_RAW = 0const ADS_SID_HEXSTRING = 1const ADS_SID_SAM = 2const ADS_SID_UPN = 3const ADS_SID_SDDL = 4const ADS_SID_WINNT_PATH = 5const ADS_SID_ACTIVE_DIRECTORY_PATH = 6const ADS_SID_SID_BINDING = 7const fldname = "C:\test2" '<----Change this to the top folder nameconst usrname = "Domain\User" '<---Change this to the user you want to add permissions forDim fso, fldr, fc, f1', fldname, usrname' Get instance of FileSystemObject.Set fso = CreateObject("Scripting.FileSystemObject")Call ApplyPerms (fldname)Set fldr = fso.GetFolder(fldname)Recurse fldr ',usrnameSet fldr = NothingSet fso = Nothingwscript.echo "done"Wscript.QuitPublic Sub Recurse( ByRef fldr)', ByRef usrname )dim subfolders,files,folder,file Set subfolders = fldr.SubFolders Set files = fldr.Files 'Display the path and all of the folders. Wscript.Echo "" Wscript.Echo fldr.Path For Each folder in subfolders Wscript.Echo folder.Name Call ApplyPerms (folder.path)', usrname) Next 'Display all of the files. For Each file in files wscript.echo file.name Call ApplyPerms (file.path)', usrname) Next 'Recurse all of the subfolders. For Each folder in subfolders Recurse folder', usrname Next Set subfolders = Nothing Set files = NothingEnd SubSub ApplyPerms(ByRef path)' , Byref usrname)Set sec = CreateObject("AdsSecurity") Set sd = sec.GetSecurityDescriptor("FILE://" & path)Set Dacl = sd.DiscretionaryAclSet oSid = CreateObject("AdsSid")oSid.SetAs ADS_SID_SAM, Cstr(usrname) sidHex = oSid.GetAs(ADS_SID_SDDL)Wscript.Echo sidHex'----Add a new ACE so User has Full Control on Files.Set ace1 = CreateObject ("AccessControlEntry")ace1.Trustee = sidHexace1.AccessMask = ADS_RIGHT_GENERIC_ALLace1.AceType = ADS_ACETYPE_ACCESS_ALLOWEDace1.AceFlags = ADS_ACEFLAG_INHERIT_ACE Or ADS_ACEFLAG_INHERIT_ONLY_ACE Or 1 dacl.AddAce ace1'----Add a new ACE so User has Full Control on Folders.Set ace2 = CreateObject ("AccessControlEntry")ace2.Trustee = sidHexace2.AccessMask = ADS_RIGHT_GENERIC_ALLace2.AceType = ADS_ACETYPE_ACCESS_ALLOWEDace2.AceFlags = ADS_ACEFLAG_INHERIT_ACE Or 1dacl.AddAce ace2sd.DiscretionaryAcl = daclsec.SetSecurityDescriptor sdEnd Sub
- Set the constant "fldname" to the folder where you want to start applying the permissions.
- Set the constant "usrname" to the name of the Domain account that you are adding the permissions for.
- Register ADsSecurity.dll (which is in the Platform SDK) by running regsvr32 ADsSecurity.dll at a command prompt.
- Run SetPerms.vbs by double-clicking it on a computer that has Windows Scripting Host (WSH) installed.
For operating system specific ADSI run-time downloads and additional information, see the following Microsoft Web site:
For more information on Windows Scripting Host, see the following article:
188135 Description of Windows Script Host (WSH)
Article ID: 266461 - Last Review: 03/29/2007 03:29:07 - Revision: 5.3
Microsoft Active Directory Service Interfaces 2.5
- kbhowto kbmsg KB266461