问题
Goal: Add a local user account share-level Read/Write permissions to an existing file share.
I'm hitting a roadblock in developing this. Apparently Microsoft wants you to add your user's ACE to the DACL and then back into the security descriptor of the share. (1). (No, NET SHARE /ADD is not available for existing shares, I was surprised.)
In theory that should be simple enough, but my main fear is doing it wrong and losing the existing share permissions (lots of network users, specific groups). This solution needs to scale to a few thousand shares. I'm developing the solution to output data about the existing DACL in case I need to back out. I should write code to interpret that log and be prepared to add them back en-masse should anything go wrong.
At the moment I'm using VBscript-- I feel PowerShell might be a bit stronger of an approach but VBscript/WMI is a known quantity.
Research: (1) http://blogs.msdn.com/b/helloworld/archive/2008/07/22/editing-share-permission.aspx
回答1:
Copy the existing ACEs to an array:
rc = shareSec.GetSecurityDescriptor(sd)
ReDim acl(UBound(sd.DACL)+1) '+1 for the new ACL we're going to add
For i = 0 To UBound(sd.DACL)
Set acl(i) = sd.DACL(i)
Next
Add the new ACE to that array:
Set acl(UBound(acl)) = NewACE(NewTrustee(username, domain), 2032127)
The functions NewTrustee()
and NewACE()
encapsulate the instructions for creating the trustee and the ACE. The number is the access mask for Full Control.
Create a new security descriptor and assign it to the share:
Set sd = wmi.Get("Win32_SecurityDescriptor").SpawnInstance_
sd.ControlFlags = flags
sd.DACL = acl
rc = shareSec.SetSecurityDescriptor(sd)
Check this page for a lot more detail information about security descriptors, trustees, ACLs and ACEs.
Full script:
Const FullControl = 2032127
' modify these variables according to your requirements:
computer = "."
share = "..."
username = "..."
domain = CreateObject("WScript.Network").UserDomain
Set wmi = GetObject("winmgmts:{impersonationLevel=impersonate}!//" _
& computer & "/root/cimv2")
Set shareSec = GetObject("winmgmts:Win32_LogicalShareSecuritySetting.Name='" _
& share & "'")
Function NewTrustee(name, domain)
Dim trustee, account
Set trustee = wmi.Get("Win32_Trustee").SpawnInstance_
trustee.Name = name
trustee.Domain = domain
Set account = wmi.Get("Win32_UserAccount.Domain='" & domain & "',Name='" _
& name & "'")
trustee.Properties_.Item("SID") = wmi.Get("Win32_SID.SID='" & account.SID _
& "'").BinaryRepresentation
Set NewTrustee = trustee
End Function
Function NewACE(trustee, permissions)
Dim ace : Set ace = wmi.Get("Win32_Ace").SpawnInstance_
ace.Properties_.Item("AccessMask") = permissions
ace.Properties_.Item("AceFlags") = 3
ace.Properties_.Item("AceType") = 0
ace.Properties_.Item("Trustee") = trustee
Set NewACE = ace
End Function
' copy existing ACEs
rc = shareSec.GetSecurityDescriptor(sd)
flags = sd.ControlFlags
ReDim acl(UBound(sd.DACL)+1) '+1 for the new ACL we're going to add
For i = 0 To UBound(sd.DACL)
Set acl(i) = sd.DACL(i)
Next
Set sd = Nothing
' add new ACE
Set acl(UBound(acl)) = NewACE(NewTrustee(username, domain), FullControl)
' prepare new security descriptor
Set sd = wmi.Get("Win32_SecurityDescriptor").SpawnInstance_
sd.ControlFlags = flags
sd.DACL = acl
' assign new security descriptor
rc = shareSec.SetSecurityDescriptor(sd)
来源:https://stackoverflow.com/questions/13333483/managing-remote-dacls-on-fileshares-win32-ace-to-win32-share