Skip to content

Commit

Permalink
Try to fix SID account issues when checking for write permissions by …
Browse files Browse the repository at this point in the history
…rewriting the function. Hopefully fix #356 #405 #395 #430
  • Loading branch information
Iridium-IO committed Jun 28, 2024
1 parent 5054395 commit 1a3fa52
Showing 1 changed file with 68 additions and 17 deletions.
85 changes: 68 additions & 17 deletions CompactGUI.Core/Analyser.vb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
Imports System.IO
Imports System.Security.AccessControl
Imports System.Security.Principal
Imports System.Threading

Public Class Analyser
Expand Down Expand Up @@ -92,34 +93,84 @@ Public Class Analyser
End Function


Public Function HasDirectoryWritePermission() As Boolean

'Public Function HasDirectoryWritePermission() As Boolean

' Try
' Dim ACRules = New DirectoryInfo(FolderName).GetAccessControl().GetAccessRules(True, True, GetType(Security.Principal.SecurityIdentifier))

' Dim identity = Security.Principal.WindowsIdentity.GetCurrent
' Dim principal = New Security.Principal.WindowsPrincipal(identity)
' Dim writeDenied = False

' For Each FSRule As FileSystemAccessRule In ACRules
' If (FSRule.FileSystemRights And FileSystemRights.Write) = 0 Then Continue For


' ' Use Translate to safely convert to NTAccount
' Dim ntAccount As Security.Principal.NTAccount = Nothing
' Try
' ntAccount = DirectCast(FSRule.IdentityReference.Translate(GetType(Security.Principal.NTAccount)), System.Security.Principal.NTAccount)
' Catch ex As Exception
' Continue For
' End Try

' If ntAccount Is Nothing OrElse Not principal.IsInRole(ntAccount.Value) Then Continue For

' If FSRule.AccessControlType = AccessControlType.Deny Then
' writeDenied = True
' Exit For
' End If

' Next

' Return Not writeDenied
' Catch ex As UnauthorizedAccessException
'
' Return False
' End Try

'End Function

Public Function HasDirectoryWritePermission() As Boolean
Try
Dim ACRules = New DirectoryInfo(FolderName).GetAccessControl().GetAccessRules(True, True, GetType(Security.Principal.NTAccount))
Dim directoryInfo = New DirectoryInfo(FolderName)
Dim directorySecurity = directoryInfo.GetAccessControl()

Dim identity = Security.Principal.WindowsIdentity.GetCurrent
Dim principal = New Security.Principal.WindowsPrincipal(identity)
Dim writeDenied = False
Dim user = WindowsIdentity.GetCurrent()
Dim userSID = user.User
Dim userGroupSIDs = user.Groups

For Each FSRule As FileSystemAccessRule In ACRules
If (FSRule.FileSystemRights And FileSystemRights.Write) = 0 Then Continue For
Dim ntAccount As Security.Principal.NTAccount = TryCast(FSRule.IdentityReference, Security.Principal.NTAccount)
Dim accessRules = directorySecurity.GetAccessRules(True, True, GetType(SecurityIdentifier))

If ntAccount Is Nothing OrElse Not principal.IsInRole(ntAccount.Value) Then Continue For
Dim writeAllowed = False
Dim writeDenied = False

If FSRule.AccessControlType = AccessControlType.Deny Then
writeDenied = True
Exit For
For Each rule As FileSystemAccessRule In accessRules
Dim fileSystemRights = rule.FileSystemRights
If (fileSystemRights And FileSystemRights.Write) > 0 Then
Dim ruleSID = DirectCast(rule.IdentityReference, SecurityIdentifier)

' Check if the rule applies to the user or any of the user's groups
If ruleSID.Equals(userSID) OrElse userGroupSIDs.Contains(ruleSID) Then
If rule.AccessControlType = AccessControlType.Allow Then
writeAllowed = True
ElseIf rule.AccessControlType = AccessControlType.Deny Then
writeDenied = True
Exit For
End If
End If
End If

Next

Return Not writeDenied
Catch ex As System.UnauthorizedAccessException
' Consider logging the exception or notifying the caller
' Write permission is considered available if it's explicitly allowed and not explicitly denied
Return writeAllowed And Not writeDenied
Catch ex As UnauthorizedAccessException

Return False
End Try

End Function



End Class

0 comments on commit 1a3fa52

Please sign in to comment.