Take the 2-minute tour ×
Server Fault is a question and answer site for system and network administrators. It's 100% free, no registration required.

One client has a Windows Domain with Home Folders, directed to a share using a GPO (\server\share\%username%).

The share has all users full control and the sub folders need permissions only for the relevant user to have full control recursively in each folder and not in any other subfolder.

For Example: John needs only access to \server\share\john recursively and should not be able to browse and access to \server\share\peter.

I have looked at Icacls and set-acl.

The folder name is the same as the login name (Peter logs in with username peter and John with username john)

Any pointers?

share|improve this question

1 Answer 1

up vote 0 down vote accepted

I have a vb.net class I wrote that you can use:

To use it:

Dim userfldr as New UserFolder("\\server\share\%username%", "username")
usrfldr.FixAcl()

The code:

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

If you want the code to get the directories for you:

        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
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.