Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Easier to ask for forgiveness than permissions

0.00/5 (No votes)
13 Jun 2014 1  
how can we limit a person's specific permissions depending on his account and privileges?

Introduction

Some people are thinking better to ask for forgiveness then permission? (Sorry for the pun in the title). In the modern computing environment, file level permissions are important in operating systems. We do not interact with them directly in most instances in our normal everyday lives. Most of us can create an administrator account, yet know little to nothing about how we can limit a person's specific permissions except for technical gurus, IT users, or power users. So, how can we limit a person's specific permissions depending on his account and privileges? I will explain how to change file level permissions below in VB.NET.

Requirements

  1. Dotnet framework 4.5 or Above
  2. Windows 7 Operating System or Above
  3. Time: Takes about 30-45 minutes to code depending on the amount of permissions that are going to be added or removed from the file. However, your mileage may differ on how fast you complete this project.

Using the code

I. Loading Users for a specific file

Our first step in this tutorial is to load the users that have permissions for a specific file into a list box. In Figure 1, as you can see the users with permissions to the file are retrieved and added to lstUsers. Example 1 below has users loaded into lstUsers to show which users it retrieved. Note: the users that are retrieved could vary depending on your system. Some test users where created and added to the file for demonstration purposes in this tutorial.

Example 1 – Users loaded into lstUsers list box.

    Private Sub BtnBrowse_Click(sender As Object, e As EventArgs) Handles BtnBrowse.Click
        OpenFileDialog1.Title = "Get access control for file"
        OpenFileDialog1.Multiselect = False
        OpenFileDialog1.InitialDirectory = "C:\Users\Jeffery\Desktop"
        If OpenFileDialog1.ShowDialog = Windows.Forms.DialogResult.OK Then
            filename = OpenFileDialog1.FileName
            Dim fi As New FileInfo(OpenFileDialog1.FileName)
            Dim fs As New FileSecurity            fs = fi.GetAccessControl
            Dim object1 As Type = Type.GetType("System.Security.Principal.NTAccount")
            For Each AuthRule As FileSystemAccessRule In fs.GetAccessRules(True, True, object1)
                lstUsers.Items.Add(AuthRule.IdentityReference.Value.ToString)
            Next
        End If
    End Sub

Figure 1 – Retrieving users and adding to lstUsers list box.

II. Viewing Permissions for a specific user

The second step in the tutorial is to view permissions for a specific user. As you can see in Example 2, I have selected the user test and his allow and deny permissions to the file show up. Notice how test does not have any deny permissions? This is not a code error. In fact, he does not have any revoked or denied permissions at all. In Figure 2, I show the code for lstUsers_SelectedIndexChanged Event which shows the permissions for a specific user that is selected from the list.

Example 2 - Selection of a specific user

 

Figure 2 - lstUsers_SelectedIndexChanged

 Private Sub lstUsers_SelectedIndexChanged(sender As Object, e As EventArgs) Handles lstUsers.SelectedIndexChanged
        user = ""
        user = lstUsers.SelectedItem.ToString
        Dim fi As New FileInfo(filename)
        Dim fs As New FileSecurity        fs = fi.GetAccessControl
        Dim object1 As Type = Type.GetType("System.Security.Principal.NTAccount")
        lstAllowPermissions.Items.Clear()
        lstDenyPermissions.Items.Clear()
        For Each AuthRule As FileSystemAccessRule In fs.GetAccessRules(True, True, object1)
            If AuthRule.IdentityReference.Value.ToString = lstUsers.SelectedItem.ToString Then
                Dim ACL_Type As String = ""
                If AuthRule.AccessControlType.Equals(AccessControlType.Deny) Then
                    ACL_Type = "Deny"
                Else
                    ACL_Type = "Allow"
                End If
 
                Dim permissions As String = ""
 
                If (AuthRule.FileSystemRights And FileSystemRights.FullControl) = FileSystemRights.FullControl Then
                    permissions = "Full Control"
                    If ACL_Type = "Allow" And permissions <> "" Then
                        lstAllowPermissions.Items.Add(permissions)
                        lstAllowPermissions.SetItemChecked(lstAllowPermissions.Items.Count - 1, True)
                    End If
                    If ACL_Type = "Deny" And permissions <> "" Then
                        lstDenyPermissions.Items.Add(permissions)
                        lstDenyPermissions.SetItemChecked(lstDenyPermissions.Items.Count - 1, True)
                    End If
                End If
                If (AuthRule.FileSystemRights And FileSystemRights.Modify) = FileSystemRights.Modify Then
                    permissions = "Modify"
                    If ACL_Type = "Allow" And permissions <> "" Then
                        lstAllowPermissions.Items.Add(permissions)
                        lstAllowPermissions.SetItemChecked(lstAllowPermissions.Items.Count - 1, True)
                    End If
                    If ACL_Type = "Deny" And permissions <> "" Then
                        lstDenyPermissions.Items.Add(permissions)
                        lstDenyPermissions.SetItemChecked(lstDenyPermissions.Items.Count - 1, True)
                    End If
                End If
                If (AuthRule.FileSystemRights And FileSystemRights.ReadAndExecute) = FileSystemRights.ReadAndExecute Then
                    permissions = "Read And Execute"
                    If ACL_Type = "Allow" And permissions <> "" Then
                        lstAllowPermissions.Items.Add(permissions)
                        lstAllowPermissions.SetItemChecked(lstAllowPermissions.Items.Count - 1, True)
                    End If
                    If ACL_Type = "Deny" And permissions <> "" Then
                        lstDenyPermissions.Items.Add(permissions)
                        lstDenyPermissions.SetItemChecked(lstDenyPermissions.Items.Count - 1, True)
                    End If
                End If
                If (AuthRule.FileSystemRights And FileSystemRights.ListDirectory) = FileSystemRights.ListDirectory Then
                    permissions = "List Directory Contents"
 
                    If ACL_Type = "Allow" And permissions <> "" Then
                        lstAllowPermissions.Items.Add(permissions)
                        lstAllowPermissions.SetItemChecked(lstAllowPermissions.Items.Count - 1, True)
                    End If
                    If ACL_Type = "Deny" And permissions <> "" Then
                        lstDenyPermissions.Items.Add(permissions)
                        lstDenyPermissions.SetItemChecked(lstDenyPermissions.Items.Count - 1, True)
                    End If
                End If
                If (AuthRule.FileSystemRights And FileSystemRights.Read) = FileSystemRights.Read Then
                    permissions = "Read"
 
                    If ACL_Type = "Allow" And permissions <> "" Then
                        lstAllowPermissions.Items.Add(permissions)
                        lstAllowPermissions.SetItemChecked(lstAllowPermissions.Items.Count - 1, True)
                    End If
                    If ACL_Type = "Deny" And permissions <> "" Then
                        lstDenyPermissions.Items.Add(permissions)
                        lstDenyPermissions.SetItemChecked(lstDenyPermissions.Items.Count - 1, True)
                    End If
                End If
                If (AuthRule.FileSystemRights And FileSystemRights.ReadPermissions) = FileSystemRights.ReadPermissions Then
                    permissions = "Read Permissions"
 
                    If ACL_Type = "Allow" And permissions <> "" Then
                        lstAllowPermissions.Items.Add(permissions)
                        lstAllowPermissions.SetItemChecked(lstAllowPermissions.Items.Count - 1, True)
                    End If
                    If ACL_Type = "Deny" And permissions <> "" Then
                        lstDenyPermissions.Items.Add(permissions)
                        lstDenyPermissions.SetItemChecked(lstDenyPermissions.Items.Count - 1, True)
                    End If
                End If
                If (AuthRule.FileSystemRights And FileSystemRights.Write) = FileSystemRights.Write Then
                    permissions = "Write"
 
                    If ACL_Type = "Allow" And permissions <> "" Then
                        lstAllowPermissions.Items.Add(permissions)
                        lstAllowPermissions.SetItemChecked(lstAllowPermissions.Items.Count - 1, True)
                    End If
                    If ACL_Type = "Deny" And permissions <> "" Then
                        lstDenyPermissions.Items.Add(permissions)
                        lstDenyPermissions.SetItemChecked(lstDenyPermissions.Items.Count - 1, True)
                    End If
                End If
                If (AuthRule.FileSystemRights And FileSystemRights.WriteAttributes) = FileSystemRights.WriteAttributes Then
                    permissions = "Write Attributes"
 
                    If ACL_Type = "Allow" And permissions <> "" Then
                        lstAllowPermissions.Items.Add(permissions)
                        lstAllowPermissions.SetItemChecked(lstAllowPermissions.Items.Count - 1, True)
                    End If
                    If ACL_Type = "Deny" And permissions <> "" Then
                        lstDenyPermissions.Items.Add(permissions)
                        lstDenyPermissions.SetItemChecked(lstDenyPermissions.Items.Count - 1, True)
                    End If
                End If
                If (AuthRule.FileSystemRights And FileSystemRights.WriteData) = FileSystemRights.WriteData Then
                    permissions = "Write Data"
 
                    If ACL_Type = "Allow" And permissions <> "" Then
                        lstAllowPermissions.Items.Add(permissions)
                        lstAllowPermissions.SetItemChecked(lstAllowPermissions.Items.Count - 1, True)
                    End If
                    If ACL_Type = "Deny" And permissions <> "" Then
                        lstDenyPermissions.Items.Add(permissions)
                        lstDenyPermissions.SetItemChecked(lstDenyPermissions.Items.Count - 1, True)
                    End If
                End If
                If (AuthRule.FileSystemRights And FileSystemRights.Traverse) = FileSystemRights.Traverse Then
                    permissions = "Trasverse Folder"
 
                    If ACL_Type = "Allow" And permissions <> "" Then
                        lstAllowPermissions.Items.Add(permissions)
                        lstAllowPermissions.SetItemChecked(lstAllowPermissions.Items.Count - 1, True)
                    End If
                    If ACL_Type = "Deny" And permissions <> "" Then
                        lstDenyPermissions.Items.Add(permissions)
                        lstDenyPermissions.SetItemChecked(lstDenyPermissions.Items.Count - 1, True)
                    End If
                End If
                If (AuthRule.FileSystemRights And FileSystemRights.ReadAttributes) = FileSystemRights.ReadAttributes Then
                    permissions = "Read Attributes"
 
                    If ACL_Type = "Allow" And permissions <> "" Then
                        lstAllowPermissions.Items.Add(permissions)
                        lstAllowPermissions.SetItemChecked(lstAllowPermissions.Items.Count - 1, True)
                    End If
                    If ACL_Type = "Deny" And permissions <> "" Then
                        lstDenyPermissions.Items.Add(permissions)
                        lstDenyPermissions.SetItemChecked(lstDenyPermissions.Items.Count - 1, True)
                    End If
                End If
                If (AuthRule.FileSystemRights And FileSystemRights.ChangePermissions) = FileSystemRights.ChangePermissions Then
                    permissions = "Change Permissions"
 
                    If ACL_Type = "Allow" And permissions <> "" Then
                        lstAllowPermissions.Items.Add(permissions)
                        lstAllowPermissions.SetItemChecked(lstAllowPermissions.Items.Count - 1, True)
                    End If
                    If ACL_Type = "Deny" And permissions <> "" Then
                        lstDenyPermissions.Items.Add(permissions)
                        lstDenyPermissions.SetItemChecked(lstDenyPermissions.Items.Count - 1, True)
                    End If
                End If
                If (AuthRule.FileSystemRights And FileSystemRights.CreateFiles) = FileSystemRights.CreateFiles Then
                    permissions = "Create Files"
 
                    If ACL_Type = "Allow" And permissions <> "" Then
                        lstAllowPermissions.Items.Add(permissions)
                        lstAllowPermissions.SetItemChecked(lstAllowPermissions.Items.Count - 1, True)
                    End If
                    If ACL_Type = "Deny" And permissions <> "" Then
                        lstDenyPermissions.Items.Add(permissions)
                        lstDenyPermissions.SetItemChecked(lstDenyPermissions.Items.Count - 1, True)
                    End If
                End If
            End If
        Next
 
    End Sub 

III.Adding/Removing Permissions

In this section, we add and change permissions but do not set them on the file. The next code section will show how to set the new permissions on the file. In this section we are adding new permissions to allow or deny permission lists with permissions to be set on the file. In Figure 3, permissions are added to allow or deny lists depending upon what is selected in the cboACLType list box. In Figure 4, the code is displayed for removing currently displayed Allow or Deny permissions. Note: you must remove the permission before changing to the next user or changes may be lost. To remove an item, uncheck it in the list box and click Remove Permissions.

Figure 3 - Add New Allow or Deny Permissions

   Private Sub BtnAdd_Click(sender As Object, e As EventArgs) Handles BtnAdd.Click
        If cboACLType.SelectedItem = "Allow" Then
            If lstAllowPermissions.Items.IndexOf(cboPermissionList.SelectedItem) = -1 And filename <> "" And lstUsers.SelectedIndex <> -1 Then 'filename must be something or a files properties have not been loaded
                lstAllowPermissions.Items.Add(cboPermissionList.SelectedItem.ToString)
                lstAllowPermissions.SetItemChecked(lstAllowPermissions.Items.Count - 1, True)
                AllowPermissions.Add(lstAllowPermissions.Items.Item(lstAllowPermissions.Items.IndexOf(cboPermissionList.SelectedItem.ToString)))
            End If
        ElseIf cboACLType.SelectedItem = "Deny" Then
            If lstDenyPermissions.Items.IndexOf(cboPermissionList.SelectedItem) = -1 And filename <> "" And lstUsers.SelectedIndex <> -1 Then
                lstDenyPermissions.Items.Add(cboPermissionList.SelectedItem.ToString)
                lstDenyPermissions.SetItemChecked(lstDenyPermissions.Items.Count - 1, True)
                DenyPermissions.Add(lstDenyPermissions.Items.Item(lstDenyPermissions.Items.IndexOf(cboPermissionList.SelectedItem.ToString)))
            End If
        End If
    End Sub 

Figure 4 - Removing Allow or Deny Permissions

  Private Sub BtnRemovePermissions_Click(sender As Object, e As EventArgs) Handles BtnRemovePermissions.Click
        Dim count As Integer
        count = lstAllowPermissions.Items.Count - 1
        If count <> -1 Then
            For allow = 0 To count
                If allow = lstAllowPermissions.Items.Count Then
                    Exit For
                End If
                If lstAllowPermissions.GetItemCheckState(allow) = CheckState.Unchecked Then 'if an item is not checked then remove it
                    lstAllowPermissions.Items.RemoveAt(allow)
                    count = count - 1
                End If
            Next
            If lstAllowPermissions.Items.Count > 0 Then
                If lstAllowPermissions.GetItemCheckState(lstAllowPermissions.Items.Count - 1) = CheckState.Unchecked Then 'remove the last item seperately because it causes an error if I remove it first thing.
                    lstAllowPermissions.Items.RemoveAt(lstAllowPermissions.Items.Count - 1)
                End If
            End If
        End If
        count = 0
        count = lstDenyPermissions.Items.Count - 1
        If count <> -1 Then
            For deny = 0 To count
                If lstDenyPermissions.GetItemCheckState(deny) = CheckState.Unchecked Then 'if an item is not checked then remove it
                    lstDenyPermissions.Items.RemoveAt(deny)
                End If
            Next
            If lstDenyPermissions.Items.Count > 0 Then
                If lstDenyPermissions.GetItemCheckState(lstDenyPermissions.Items.Count - 1) = CheckState.Unchecked Then 'remove the last item seperately because it causes an error if I remove it first thing.
                    lstDenyPermissions.Items.RemoveAt(lstDenyPermissions.Items.Count - 1)
                End If
            Else
            End If
        End If
    End Sub

In Figures 5+6, I use the selectedindexchanged event of deny and allow permission list boxes to change permissions based on what is checked.

Figure 5 - Adding changed Allow permissions

 Private Sub lstAllowPermissions_SelectedIndexChanged(sender As Object, e As EventArgs) Handles lstAllowPermissions.SelectedIndexChanged
        AllowPermissions.Clear() 'clear the list of allowpermissions before adding the new allow permissions
        For i = 0 To lstAllowPermissions.CheckedItems.Count - 1
            AllowPermissions.Add(lstAllowPermissions.CheckedItems.Item(i).ToString)
        Next
    End Sub 

Figure 6 - Adding changed Deny permissions

   Private Sub lstDenyPermissions_SelectedIndexChanged(sender As Object, e As EventArgs) Handles lstDenyPermissions.SelectedIndexChanged
        DenyPermissions.Clear() 'clear the list of all deny permissions before adding the new deny permissions
        For i = 0 To lstDenyPermissions.CheckedItems.Count - 1
            DenyPermissions.Add(lstDenyPermissions.CheckedItems.Item(i).ToString)
        Next
    End Sub  

In example 3, you can see when looking at the picture that I added a deny permission of List Directory Contents for the user test. To add the deny permission, I selected the permission to deny and Deny from the combo boxes and then clicked add permissions. Note: deny permissions override allow permissions for local files so I do not need to revoke a permission if it is denied.

Example 3 - Adding a deny permission of List Directory contents to user test.

IV.Setting Permissions

In Figure 7, I call the SetPermissions function for the SetPermissions Button. In Figure 8, the SetPermissions function sets the permissions for our file we selected in Figure 1.

Figure 7 - Set Permissions Button code

    Private Sub BtnSetPermissions_Click(sender As Object, e As EventArgs) Handles BtnSetPermissions.Click
        If SetPermissions() = True Then
            MsgBox("done!")
        End If
    End Sub

Figure 8- SetPermissions Function sets permissions for the file we selected.

  Public Function SetPermissions() As Boolean
        Dim fi As New FileInfo(filename)
        Dim fs As New FileSecurity
        fs = fi.GetAccessControl
        Dim object1 As Type = Type.GetType("System.Security.Principal.NTAccount")
        Dim newrule As FileSystemAccessRule
        If AllowPermissions.Count > 0 Then
            For i = 0 To AllowPermissions.Count - 1
                Select Case AllowPermissions.Item(i)
                    Case Is = "Read"
                        newrule = New FileSystemAccessRule(user, FileSystemRights.Read, AccessControlType.Allow)
                        fs.AddAccessRule(newrule)
                        File.SetAccessControl(filename, fs)
                    Case Is = "Write"
                        newrule = New FileSystemAccessRule(user, FileSystemRights.Write, AccessControlType.Allow)
                        fs.AddAccessRule(newrule)
                        File.SetAccessControl(filename, fs)
                    Case Is = "List Directory Contents"
                        newrule = New FileSystemAccessRule(user, FileSystemRights.ListDirectory, AccessControlType.Allow)
                        fs.AddAccessRule(newrule)
                        File.SetAccessControl(filename, fs)
                    Case Is = "Create Files"
                        newrule = New FileSystemAccessRule(user, FileSystemRights.CreateFiles, AccessControlType.Allow)
                        fs.AddAccessRule(newrule)
                        File.SetAccessControl(filename, fs)
                    Case Is = "Read And Execute"
                        newrule = New FileSystemAccessRule(user, FileSystemRights.ReadAndExecute, AccessControlType.Allow)
                        fs.AddAccessRule(newrule)
                        File.SetAccessControl(filename, fs)
                    Case Is = "Transverse Folder"
                        newrule = New FileSystemAccessRule(user, FileSystemRights.Traverse, AccessControlType.Allow)
                        fs.AddAccessRule(newrule)
                        File.SetAccessControl(filename, fs)
                    Case Is = "Full Control"
                        newrule = New FileSystemAccessRule(user, FileSystemRights.FullControl, AccessControlType.Allow)
                        fs.AddAccessRule(newrule)
                        File.SetAccessControl(filename, fs)
                    Case Is = "Read Attributes"
                        newrule = New FileSystemAccessRule(user, FileSystemRights.ReadAttributes, AccessControlType.Allow)
                        fs.AddAccessRule(newrule)
                        File.SetAccessControl(filename, fs)
                    Case Is = "Read extended Attributes"
                        newrule = New FileSystemAccessRule(user, FileSystemRights.ReadExtendedAttributes, AccessControlType.Allow)
                        fs.AddAccessRule(newrule)
                        File.SetAccessControl(filename, fs)
                    Case Is = "Modify"
                        newrule = New FileSystemAccessRule(user, FileSystemRights.Modify, AccessControlType.Allow)
                        fs.AddAccessRule(newrule)
                        File.SetAccessControl(filename, fs)
                    Case Is = "Append Data"
                        newrule = New FileSystemAccessRule(user, FileSystemRights.AppendData, AccessControlType.Allow)
                        fs.AddAccessRule(newrule)
                        File.SetAccessControl(filename, fs)
                    Case Is = "Change Permissions"
                        newrule = New FileSystemAccessRule(user, FileSystemRights.ChangePermissions, AccessControlType.Allow)
                        fs.AddAccessRule(newrule)
                        File.SetAccessControl(filename, fs)
                End Select
                newrule = Nothing
            Next i
        End If
        newrule = Nothing
        If DenyPermissions.Count > 0 Then
            For i = 0 To DenyPermissions.Count - 1
                Select Case DenyPermissions.Item(i)
                    Case Is = "Read"
                        newrule = New FileSystemAccessRule(user, FileSystemRights.Read, AccessControlType.Deny)
                        fs.AddAccessRule(newrule)
                        File.SetAccessControl(filename, fs)
                    Case Is = "Write"
                        newrule = New FileSystemAccessRule(user, FileSystemRights.Write, AccessControlType.Deny)
                        fs.AddAccessRule(newrule)
                        File.SetAccessControl(filename, fs)
                    Case Is = "List Directory Contents"
                        newrule = New FileSystemAccessRule(user, FileSystemRights.ListDirectory, AccessControlType.Deny)
                        fs.AddAccessRule(newrule)
                        File.SetAccessControl(filename, fs)
                    Case Is = "Create Files"
                        newrule = New FileSystemAccessRule(user, FileSystemRights.CreateFiles, AccessControlType.Deny)
                        fs.AddAccessRule(newrule)
                        File.SetAccessControl(filename, fs)
                    Case Is = "Read And Execute"
                        newrule = New FileSystemAccessRule(user, FileSystemRights.ReadAndExecute, AccessControlType.Deny)
                        fs.AddAccessRule(newrule)
                        File.SetAccessControl(filename, fs)
                    Case Is = "Transverse Folder"
                        newrule = New FileSystemAccessRule(user, FileSystemRights.Traverse, AccessControlType.Deny)
                        fs.AddAccessRule(newrule)
                        File.SetAccessControl(filename, fs)
                    Case Is = "Full Control"
                        newrule = New FileSystemAccessRule(user, FileSystemRights.FullControl, AccessControlType.Deny)
                        fs.AddAccessRule(newrule)
                        File.SetAccessControl(filename, fs)
                    Case Is = "Read Attributes"
                        newrule = New FileSystemAccessRule(user, FileSystemRights.ReadAttributes, AccessControlType.Deny)
                        fs.AddAccessRule(newrule)
                        File.SetAccessControl(filename, fs)
                    Case Is = "Read extended Attributes"
                        newrule = New FileSystemAccessRule(user, FileSystemRights.ReadExtendedAttributes, AccessControlType.Deny)
                        fs.AddAccessRule(newrule)
                        File.SetAccessControl(filename, fs)
                    Case Is = "Modify"
                        newrule = New FileSystemAccessRule(user, FileSystemRights.Modify, AccessControlType.Deny)
                        fs.AddAccessRule(newrule)
                        File.SetAccessControl(filename, fs)
                    Case Is = "Append Data"
                        newrule = New FileSystemAccessRule(user, FileSystemRights.AppendData, AccessControlType.Deny)
                        fs.AddAccessRule(newrule)
                        File.SetAccessControl(filename, fs)
                    Case Is = "Change Permissions"
                        newrule = New FileSystemAccessRule(user, FileSystemRights.ChangePermissions, AccessControlType.Deny)
                        fs.AddAccessRule(newrule)
                        File.SetAccessControl(filename, fs)
                End Select
                newrule = Nothing
            Next i
        End If
        Return True
    End Function

Example 4 - showing how the deny permissions were applied to the file.

In Example 4, see how the Permission Entry for devices (devices.txt file) Dialog above is showing only the Deny permission of List Directory Contents and there is a new Deny rule added? The new rule is added when the List folder permission is changed to deny. This rule is only applied though when we click BtnSet Permissions (also called the Set Permissions button) before moving onto the next user. Note: these are local file permissions and do not include changing any active directory permissions.

History

 

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here