Eu tenho uma classe vb.net que escrevi que você pode usar:
Para usá-lo:
Dim userfldr as New UserFolder("\server\share\%username%", "username")
usrfldr.FixAcl()
O código:
Imports System.Text
Public Class UserFolder
Private _folder As System.IO.DirectoryInfo
Private _security As System.Security.AccessControl.DirectorySecurity
Private _aclVisible As Boolean = True
Private _owner As String
Private _baseDirectory As String
Private _userName As String
Private _adminIdentity As Security.Principal.NTAccount
Private _userIdentity As Security.Principal.NTAccount
Private _systemIdentity As Security.Principal.NTAccount
Private _beQuick As Boolean
Public ReadOnly Property adminIdentity() As Security.Principal.NTAccount
Get
Return _adminIdentity
End Get
End Property
Public ReadOnly Property userIdentity() As Security.Principal.NTAccount
Get
Return _userIdentity
End Get
End Property
Public ReadOnly Property systemIdentity() As Security.Principal.NTAccount
Get
Return _systemIdentity
End Get
End Property
Public ReadOnly Property aclVisible() As Boolean
Get
Return _aclVisible
End Get
End Property
Public ReadOnly Property owner() As String
Get
Return _owner
End Get
End Property
Public ReadOnly Property HasInheritances() As Boolean
Get
Dim returnValue As Boolean = False
For Each a As System.Security.AccessControl.FileSystemAccessRule In _security.GetAccessRules(True, True, GetType(System.Security.Principal.NTAccount)).OfType(Of System.Security.AccessControl.FileSystemAccessRule)()
If a.IsInherited Then
returnValue = True
Exit For
End If
Next
Return returnValue
End Get
End Property
Public ReadOnly Property Users() As String
Get
Dim userList As New StringBuilder
For Each a As System.Security.AccessControl.FileSystemAccessRule In _security.GetAccessRules(True, True, GetType(System.Security.Principal.NTAccount)).OfType(Of System.Security.AccessControl.FileSystemAccessRule)()
userList.AppendLine(a.AccessControlType.ToString & " " & a.IdentityReference.Value & " (" & a.FileSystemRights.ToString & ")")
Next
Return userList.ToString
End Get
End Property
Public ReadOnly Property Folder() As String
Get
Return _folder.FullName
End Get
End Property
''' <summary>
''' Creates a new instance of Class
''' </summary>
''' <param name="directoryTemplate">The path of the directory you want to check user security. The path should have the variable %username% in it.</param>
''' <param name="beQuick">Can Fix ACLs quicker by making only the subfolders inherit, instead of subfolders and files.</param>
''' <remarks></remarks>
Public Sub New(ByVal directoryTemplate As String, ByVal username As String, Optional ByVal beQuick As Boolean = False)
My.User.InitializeWithWindowsUser()
_beQuick = beQuick
_userName = username
_folder = New IO.DirectoryInfo(directoryTemplate.Replace("%username%", username))
Dim adSettings As New ADEditor.ADEditorSettings
_adminIdentity = New Security.Principal.NTAccount(adSettings.domain, "Domain Admins")
_userIdentity = New Security.Principal.NTAccount(adSettings.domain, _userName)
_systemIdentity = New Security.Principal.NTAccount("NT AUTHORITY", "SYSTEM")
Try
My.User.InitializeWithWindowsUser()
_security = _folder.GetAccessControl(Security.AccessControl.AccessControlSections.All)
Dim account As System.Security.Principal.NTAccount = _security.GetOwner(GetType(System.Security.Principal.NTAccount))
_owner = account.Value.Split("\")(1)
Catch noUserEx As Security.Principal.IdentityNotMappedException
' Do Nothing
Catch ex As Exception
FixAcl()
End Try
End Sub
Public Sub GiveAdminFullRights()
_security = _folder.GetAccessControl
Dim adminFullPermissions As New Security.AccessControl.FileSystemAccessRule(adminIdentity, Security.AccessControl.FileSystemRights.FullControl, Security.AccessControl.InheritanceFlags.ContainerInherit Or Security.AccessControl.InheritanceFlags.ObjectInherit, Security.AccessControl.PropagationFlags.None, Security.AccessControl.AccessControlType.Allow)
_security.AddAccessRule(adminFullPermissions)
_folder.SetAccessControl(_security)
End Sub
Public Sub FixAcl(Optional ByVal beQuick As Boolean = False)
Try
' Make Domain Admin Owner so that the code can change permissions
Dim setOwnerSec As New Security.AccessControl.DirectorySecurity()
setOwnerSec.SetOwner(adminIdentity)
_folder.SetAccessControl(setOwnerSec)
'Make sure that the user's folder doesn't inherit permissions
_security.SetAccessRuleProtection(True, False)
' Clear out existing permissions for the users permissions we are setting
Dim accessRules As System.Security.AccessControl.AuthorizationRuleCollection
accessRules = _security.GetAccessRules(True, False, System.Type.GetType("System.Security.Principal.NTAccount"))
For Each r As System.Security.AccessControl.AuthorizationRule In accessRules
_security.PurgeAccessRules(r.IdentityReference)
Next
' Declare Permissions
Dim adminChangePermissions As New Security.AccessControl.FileSystemAccessRule(adminIdentity, Security.AccessControl.FileSystemRights.ChangePermissions, Security.AccessControl.InheritanceFlags.ContainerInherit Or Security.AccessControl.InheritanceFlags.ObjectInherit, Security.AccessControl.PropagationFlags.None, Security.AccessControl.AccessControlType.Allow)
Dim adminReadPermissions As New Security.AccessControl.FileSystemAccessRule(adminIdentity, Security.AccessControl.FileSystemRights.ReadPermissions, Security.AccessControl.InheritanceFlags.ContainerInherit Or Security.AccessControl.InheritanceFlags.ObjectInherit, Security.AccessControl.PropagationFlags.None, Security.AccessControl.AccessControlType.Allow)
Dim adminListContainers As New Security.AccessControl.FileSystemAccessRule(adminIdentity, Security.AccessControl.FileSystemRights.ListDirectory, Security.AccessControl.InheritanceFlags.ContainerInherit Or Security.AccessControl.InheritanceFlags.ObjectInherit, Security.AccessControl.PropagationFlags.None, Security.AccessControl.AccessControlType.Allow)
Dim userFull As New Security.AccessControl.FileSystemAccessRule(userIdentity, Security.AccessControl.FileSystemRights.FullControl, Security.AccessControl.InheritanceFlags.ContainerInherit Or Security.AccessControl.InheritanceFlags.ObjectInherit, Security.AccessControl.PropagationFlags.None, Security.AccessControl.AccessControlType.Allow)
Dim systemFull As New Security.AccessControl.FileSystemAccessRule(systemIdentity, Security.AccessControl.FileSystemRights.FullControl, Security.AccessControl.InheritanceFlags.ContainerInherit Or Security.AccessControl.InheritanceFlags.ObjectInherit, Security.AccessControl.PropagationFlags.None, Security.AccessControl.AccessControlType.Allow)
Dim userDeleteDeny As New Security.AccessControl.FileSystemAccessRule(userIdentity, Security.AccessControl.FileSystemRights.Delete, Security.AccessControl.InheritanceFlags.None, Security.AccessControl.PropagationFlags.NoPropagateInherit, Security.AccessControl.AccessControlType.Deny)
' Add permissions to security object
_security.AddAccessRule(adminChangePermissions)
_security.AddAccessRule(adminReadPermissions)
_security.AddAccessRule(adminListContainers)
_security.AddAccessRule(userFull)
_security.AddAccessRule(userDeleteDeny)
_security.AddAccessRule(systemFull)
_security.SetOwner(userIdentity)
_folder.SetAccessControl(_security)
' All files and folders within the user's directory need to inherit
' from the user's directory
If _beQuick Then
AllowADirectorysDirectoriesandFilesToInheritRecursivelyQuick(_folder.FullName)
Else
AllowADirectorysDirectoriesandFilesToInheritRecursively(_folder.FullName)
End If
Dim account As System.Security.Principal.NTAccount = _security.GetOwner(GetType(System.Security.Principal.NTAccount))
_owner = account.Value.Split("\")(1)
Catch invalidUserEx As System.Security.Principal.IdentityNotMappedException
MessageBox.Show("The username '" & userIdentity.Value & "' doesn't exist, so the ACL cannot be fixed.", "Invalid user")
End Try
End Sub
Private Sub AllowADirectorysFilesToInherit(ByVal directoryPath As String)
For Each f As String In IO.Directory.GetFiles(directoryPath)
Dim fileAcl As New Security.AccessControl.FileSecurity()
fileAcl.SetOwner(adminIdentity)
IO.File.SetAccessControl(f, fileAcl)
fileAcl.SetAccessRuleProtection(False, False)
fileAcl.SetOwner(userIdentity)
IO.File.SetAccessControl(f, fileAcl)
Next
End Sub
Private Sub AllowADirectorysDirectoriesandFilesToInheritRecursively(ByVal directoryPath As String)
AllowADirectorysFilesToInherit(directoryPath)
For Each d As String In IO.Directory.GetDirectories(directoryPath)
Dim directoryAcl As New Security.AccessControl.DirectorySecurity
directoryAcl.SetOwner(adminIdentity)
IO.Directory.SetAccessControl(d, directoryAcl)
directoryAcl.SetAccessRuleProtection(False, False)
directoryAcl.SetOwner(userIdentity)
IO.Directory.SetAccessControl(d, directoryAcl)
AllowADirectorysFilesToInherit(d)
AllowADirectorysDirectoriesandFilesToInheritRecursively(d)
Next
End Sub
Private Sub AllowADirectorysDirectoriesandFilesToInheritRecursivelyQuick(ByVal directoryPath As String)
AllowADirectorysFilesToInherit(directoryPath)
For Each d As String In IO.Directory.GetDirectories(directoryPath)
Dim directoryAcl As New Security.AccessControl.DirectorySecurity
directoryAcl.SetOwner(adminIdentity)
IO.Directory.SetAccessControl(d, directoryAcl)
directoryAcl.SetAccessRuleProtection(False, False)
directoryAcl.SetOwner(userIdentity)
IO.Directory.SetAccessControl(d, directoryAcl)
AllowADirectorysDirectoriesandFilesToInheritRecursivelyQuick(d)
Next
End Sub
End Class
Se você quiser que o código obtenha os diretórios para você:
Dim homePath As String = "\server\share"
Dim userName As String
Dim homeDirectories() As String
My.User.InitializeWithWindowsUser()
homeDirectories = IO.Directory.GetDirectories(homePath)
For Each d As String In homeDirectories
userName = d.Substring(d.LastIndexOf("\") + 1)
Dim folder As New UserFolder(d, userName)
If folder.aclVisible = True Then
folder.FixAcl()
End If
Next