Skip to content

Commit 1a3fa52

Browse files
committed
Try to fix SID account issues when checking for write permissions by rewriting the function. Hopefully fix #356 #405 #395 #430
1 parent 5054395 commit 1a3fa52

File tree

1 file changed

+68
-17
lines changed

1 file changed

+68
-17
lines changed

CompactGUI.Core/Analyser.vb

Lines changed: 68 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
Imports System.IO
22
Imports System.Security.AccessControl
3+
Imports System.Security.Principal
34
Imports System.Threading
45

56
Public Class Analyser
@@ -92,34 +93,84 @@ Public Class Analyser
9293
End Function
9394

9495

95-
Public Function HasDirectoryWritePermission() As Boolean
9696

97+
'Public Function HasDirectoryWritePermission() As Boolean
98+
99+
' Try
100+
' Dim ACRules = New DirectoryInfo(FolderName).GetAccessControl().GetAccessRules(True, True, GetType(Security.Principal.SecurityIdentifier))
101+
102+
' Dim identity = Security.Principal.WindowsIdentity.GetCurrent
103+
' Dim principal = New Security.Principal.WindowsPrincipal(identity)
104+
' Dim writeDenied = False
105+
106+
' For Each FSRule As FileSystemAccessRule In ACRules
107+
' If (FSRule.FileSystemRights And FileSystemRights.Write) = 0 Then Continue For
108+
109+
110+
' ' Use Translate to safely convert to NTAccount
111+
' Dim ntAccount As Security.Principal.NTAccount = Nothing
112+
' Try
113+
' ntAccount = DirectCast(FSRule.IdentityReference.Translate(GetType(Security.Principal.NTAccount)), System.Security.Principal.NTAccount)
114+
' Catch ex As Exception
115+
' Continue For
116+
' End Try
117+
118+
' If ntAccount Is Nothing OrElse Not principal.IsInRole(ntAccount.Value) Then Continue For
119+
120+
' If FSRule.AccessControlType = AccessControlType.Deny Then
121+
' writeDenied = True
122+
' Exit For
123+
' End If
124+
125+
' Next
126+
127+
' Return Not writeDenied
128+
' Catch ex As UnauthorizedAccessException
129+
'
130+
' Return False
131+
' End Try
132+
133+
'End Function
134+
135+
Public Function HasDirectoryWritePermission() As Boolean
97136
Try
98-
Dim ACRules = New DirectoryInfo(FolderName).GetAccessControl().GetAccessRules(True, True, GetType(Security.Principal.NTAccount))
137+
Dim directoryInfo = New DirectoryInfo(FolderName)
138+
Dim directorySecurity = directoryInfo.GetAccessControl()
99139

100-
Dim identity = Security.Principal.WindowsIdentity.GetCurrent
101-
Dim principal = New Security.Principal.WindowsPrincipal(identity)
102-
Dim writeDenied = False
140+
Dim user = WindowsIdentity.GetCurrent()
141+
Dim userSID = user.User
142+
Dim userGroupSIDs = user.Groups
103143

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

108-
If ntAccount Is Nothing OrElse Not principal.IsInRole(ntAccount.Value) Then Continue For
146+
Dim writeAllowed = False
147+
Dim writeDenied = False
109148

110-
If FSRule.AccessControlType = AccessControlType.Deny Then
111-
writeDenied = True
112-
Exit For
149+
For Each rule As FileSystemAccessRule In accessRules
150+
Dim fileSystemRights = rule.FileSystemRights
151+
If (fileSystemRights And FileSystemRights.Write) > 0 Then
152+
Dim ruleSID = DirectCast(rule.IdentityReference, SecurityIdentifier)
153+
154+
' Check if the rule applies to the user or any of the user's groups
155+
If ruleSID.Equals(userSID) OrElse userGroupSIDs.Contains(ruleSID) Then
156+
If rule.AccessControlType = AccessControlType.Allow Then
157+
writeAllowed = True
158+
ElseIf rule.AccessControlType = AccessControlType.Deny Then
159+
writeDenied = True
160+
Exit For
161+
End If
162+
End If
113163
End If
114-
115164
Next
116165

117-
Return Not writeDenied
118-
Catch ex As System.UnauthorizedAccessException
119-
' Consider logging the exception or notifying the caller
166+
' Write permission is considered available if it's explicitly allowed and not explicitly denied
167+
Return writeAllowed And Not writeDenied
168+
Catch ex As UnauthorizedAccessException
169+
120170
Return False
121171
End Try
122-
123172
End Function
124173

174+
175+
125176
End Class

0 commit comments

Comments
 (0)