Last active
January 21, 2019 13:22
-
-
Save EmileSonneveld/3b3614d53f86be14110b93cb947951e7 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Security; | |
using System.Security.AccessControl; | |
namespace GCAWeb.Utils | |
{ | |
/// <span class="code-SummaryComment"><summary> | |
/// Configuring a Web site through a Web interface can be tricky. | |
/// If one is to read and write various files, it is useful to know | |
/// in advance if you have the authority to do so. | |
/// | |
/// This class contains a simple answer to a | |
/// potentially complicated question | |
/// "Can I read this file or can I write to this file?" | |
/// | |
/// Using the "rule of least privilege", | |
/// one must check not only is access granted but | |
/// is it denied at any point including a possibly recursive check of groups. | |
/// | |
/// For this simple check, a look at the user and immediate groups are only checked. | |
/// | |
/// This class could be expanded to identify if the applicable allow/deny rule | |
/// was explicit or inherited | |
/// | |
/// </summary></span> | |
public class UserFileAccessRights | |
{ | |
private readonly string _path; | |
private readonly System.Security.Principal.WindowsIdentity _principal; | |
private readonly bool _denyAppendData = false; | |
private readonly bool _denyChangePermissions = false; | |
private readonly bool _denyCreateDirectories = false; | |
private readonly bool _denyCreateFiles = false; | |
private readonly bool _denyDelete = false; | |
private readonly bool _denyDeleteSubdirectoriesAndFiles = false; | |
private readonly bool _denyExecuteFile = false; | |
private readonly bool _denyFullControl = false; | |
private readonly bool _denyListDirectory = false; | |
private readonly bool _denyModify = false; | |
private readonly bool _denyRead = false; | |
private readonly bool _denyReadAndExecute = false; | |
private readonly bool _denyReadAttributes = false; | |
private readonly bool _denyReadData = false; | |
private readonly bool _denyReadExtendedAttributes = false; | |
private readonly bool _denyReadPermissions = false; | |
private readonly bool _denySynchronize = false; | |
private readonly bool _denyTakeOwnership = false; | |
private readonly bool _denyTraverse = false; | |
private readonly bool _denyWrite = false; | |
private readonly bool _denyWriteAttributes = false; | |
private readonly bool _denyWriteData = false; | |
private readonly bool _denyWriteExtendedAttributes = false; | |
private readonly bool _allowAppendData = false; | |
private readonly bool _allowChangePermissions = false; | |
private readonly bool _allowCreateDirectories = false; | |
private readonly bool _allowCreateFiles = false; | |
private readonly bool _allowDelete = false; | |
private readonly bool _allowDeleteSubdirectoriesAndFiles = false; | |
private readonly bool _allowExecuteFile = false; | |
private readonly bool _allowFullControl = false; | |
private readonly bool _allowListDirectory = false; | |
private readonly bool _allowModify = false; | |
private readonly bool _allowRead = false; | |
private readonly bool _allowReadAndExecute = false; | |
private readonly bool _allowReadAttributes = false; | |
private readonly bool _allowReadData = false; | |
private readonly bool _allowReadExtendedAttributes = false; | |
private readonly bool _allowReadPermissions = false; | |
private readonly bool _allowSynchronize = false; | |
private readonly bool _allowTakeOwnership = false; | |
private readonly bool _allowTraverse = false; | |
private readonly bool _allowWrite = false; | |
private readonly bool _allowWriteAttributes = false; | |
private readonly bool _allowWriteData = false; | |
private readonly bool _allowWriteExtendedAttributes = false; | |
public bool canAppendData() { return !_denyAppendData && _allowAppendData; } | |
public bool canChangePermissions() | |
{ return !_denyChangePermissions && _allowChangePermissions; } | |
public bool canCreateDirectories() | |
{ return !_denyCreateDirectories && _allowCreateDirectories; } | |
public bool canCreateFiles() { return !_denyCreateFiles && _allowCreateFiles; } | |
public bool canDelete() { return !_denyDelete && _allowDelete; } | |
public bool canDeleteSubdirectoriesAndFiles() | |
{ | |
return !_denyDeleteSubdirectoriesAndFiles && | |
_allowDeleteSubdirectoriesAndFiles; | |
} | |
public bool canExecuteFile() { return !_denyExecuteFile && _allowExecuteFile; } | |
public bool canFullControl() { return !_denyFullControl && _allowFullControl; } | |
public bool canListDirectory() | |
{ return !_denyListDirectory && _allowListDirectory; } | |
public bool canModify() { return !_denyModify && _allowModify; } | |
public bool canRead() { return !_denyRead && _allowRead; } | |
public bool canReadAndExecute() | |
{ return !_denyReadAndExecute && _allowReadAndExecute; } | |
public bool canReadAttributes() | |
{ return !_denyReadAttributes && _allowReadAttributes; } | |
public bool canReadData() { return !_denyReadData && _allowReadData; } | |
public bool canReadExtendedAttributes() | |
{ | |
return !_denyReadExtendedAttributes && | |
_allowReadExtendedAttributes; | |
} | |
public bool canReadPermissions() | |
{ return !_denyReadPermissions && _allowReadPermissions; } | |
public bool canSynchronize() { return !_denySynchronize && _allowSynchronize; } | |
public bool canTakeOwnership() | |
{ return !_denyTakeOwnership && _allowTakeOwnership; } | |
public bool canTraverse() { return !_denyTraverse && _allowTraverse; } | |
public bool canWrite() { return !_denyWrite && _allowWrite; } | |
public bool canWriteAttributes() | |
{ return !_denyWriteAttributes && _allowWriteAttributes; } | |
public bool canWriteData() { return !_denyWriteData && _allowWriteData; } | |
public bool canWriteExtendedAttributes() | |
{ | |
return !_denyWriteExtendedAttributes && | |
_allowWriteExtendedAttributes; | |
} | |
/// <span class="code-SummaryComment"><summary> | |
/// Simple accessor | |
/// </summary></span> | |
/// <span class="code-SummaryComment"><returns></returns></span> | |
public System.Security.Principal.WindowsIdentity getWindowsIdentity() | |
{ | |
return _principal; | |
} | |
/// <span class="code-SummaryComment"><summary> | |
/// Simple accessor | |
/// </summary></span> | |
/// <span class="code-SummaryComment"><returns></returns></span> | |
public String getPath() | |
{ | |
return _path; | |
} | |
/// <span class="code-SummaryComment"><summary> | |
/// Convenience constructor assumes the current user | |
/// </summary></span> | |
/// <span class="code-SummaryComment"><param name="path"></param></span> | |
public UserFileAccessRights(string path) : | |
this(path, System.Security.Principal.WindowsIdentity.GetCurrent()) | |
{ } | |
/// <span class="code-SummaryComment"><summary> | |
/// Supply the path to the file or directory and a user or group. | |
/// Access checks are done | |
/// during instantiation to ensure we always have a valid object | |
/// </summary></span> | |
/// <span class="code-SummaryComment"><param name="path"></param></span> | |
/// <span class="code-SummaryComment"><param name="principal"></param></span> | |
public UserFileAccessRights(string path, | |
System.Security.Principal.WindowsIdentity principal) | |
{ | |
this._path = path; | |
this._principal = principal; | |
try | |
{ | |
System.IO.FileInfo fi = new System.IO.FileInfo(_path); | |
AuthorizationRuleCollection acl = fi.GetAccessControl().GetAccessRules | |
(true, true, typeof(System.Security.Principal.SecurityIdentifier)); | |
for (int i = 0; i < acl.Count; i++) | |
{ | |
System.Security.AccessControl.FileSystemAccessRule rule = | |
(System.Security.AccessControl.FileSystemAccessRule)acl[i]; | |
if (_principal.User.Equals(rule.IdentityReference)) | |
{ | |
if (System.Security.AccessControl.AccessControlType.Deny.Equals | |
(rule.AccessControlType)) | |
{ | |
if (contains(FileSystemRights.AppendData, rule)) | |
_denyAppendData = true; | |
if (contains(FileSystemRights.ChangePermissions, rule)) | |
_denyChangePermissions = true; | |
if (contains(FileSystemRights.CreateDirectories, rule)) | |
_denyCreateDirectories = true; | |
if (contains(FileSystemRights.CreateFiles, rule)) | |
_denyCreateFiles = true; | |
if (contains(FileSystemRights.Delete, rule)) | |
_denyDelete = true; | |
if (contains(FileSystemRights.DeleteSubdirectoriesAndFiles, | |
rule)) _denyDeleteSubdirectoriesAndFiles = true; | |
if (contains(FileSystemRights.ExecuteFile, rule)) | |
_denyExecuteFile = true; | |
if (contains(FileSystemRights.FullControl, rule)) | |
_denyFullControl = true; | |
if (contains(FileSystemRights.ListDirectory, rule)) | |
_denyListDirectory = true; | |
if (contains(FileSystemRights.Modify, rule)) | |
_denyModify = true; | |
if (contains(FileSystemRights.Read, rule)) _denyRead = true; | |
if (contains(FileSystemRights.ReadAndExecute, rule)) | |
_denyReadAndExecute = true; | |
if (contains(FileSystemRights.ReadAttributes, rule)) | |
_denyReadAttributes = true; | |
if (contains(FileSystemRights.ReadData, rule)) | |
_denyReadData = true; | |
if (contains(FileSystemRights.ReadExtendedAttributes, rule)) | |
_denyReadExtendedAttributes = true; | |
if (contains(FileSystemRights.ReadPermissions, rule)) | |
_denyReadPermissions = true; | |
if (contains(FileSystemRights.Synchronize, rule)) | |
_denySynchronize = true; | |
if (contains(FileSystemRights.TakeOwnership, rule)) | |
_denyTakeOwnership = true; | |
if (contains(FileSystemRights.Traverse, rule)) | |
_denyTraverse = true; | |
if (contains(FileSystemRights.Write, rule)) _denyWrite = true; | |
if (contains(FileSystemRights.WriteAttributes, rule)) | |
_denyWriteAttributes = true; | |
if (contains(FileSystemRights.WriteData, rule)) | |
_denyWriteData = true; | |
if (contains(FileSystemRights.WriteExtendedAttributes, rule)) | |
_denyWriteExtendedAttributes = true; | |
} | |
else if (System.Security.AccessControl.AccessControlType. | |
Allow.Equals(rule.AccessControlType)) | |
{ | |
if (contains(FileSystemRights.AppendData, rule)) | |
_allowAppendData = true; | |
if (contains(FileSystemRights.ChangePermissions, rule)) | |
_allowChangePermissions = true; | |
if (contains(FileSystemRights.CreateDirectories, rule)) | |
_allowCreateDirectories = true; | |
if (contains(FileSystemRights.CreateFiles, rule)) | |
_allowCreateFiles = true; | |
if (contains(FileSystemRights.Delete, rule)) | |
_allowDelete = true; | |
if (contains(FileSystemRights.DeleteSubdirectoriesAndFiles, | |
rule)) _allowDeleteSubdirectoriesAndFiles = true; | |
if (contains(FileSystemRights.ExecuteFile, rule)) | |
_allowExecuteFile = true; | |
if (contains(FileSystemRights.FullControl, rule)) | |
_allowFullControl = true; | |
if (contains(FileSystemRights.ListDirectory, rule)) | |
_allowListDirectory = true; | |
if (contains(FileSystemRights.Modify, rule)) | |
_allowModify = true; | |
if (contains(FileSystemRights.Read, rule)) _allowRead = true; | |
if (contains(FileSystemRights.ReadAndExecute, rule)) | |
_allowReadAndExecute = true; | |
if (contains(FileSystemRights.ReadAttributes, rule)) | |
_allowReadAttributes = true; | |
if (contains(FileSystemRights.ReadData, rule)) | |
_allowReadData = true; | |
if (contains(FileSystemRights.ReadExtendedAttributes, rule)) | |
_allowReadExtendedAttributes = true; | |
if (contains(FileSystemRights.ReadPermissions, rule)) | |
_allowReadPermissions = true; | |
if (contains(FileSystemRights.Synchronize, rule)) | |
_allowSynchronize = true; | |
if (contains(FileSystemRights.TakeOwnership, rule)) | |
_allowTakeOwnership = true; | |
if (contains(FileSystemRights.Traverse, rule)) | |
_allowTraverse = true; | |
if (contains(FileSystemRights.Write, rule)) | |
_allowWrite = true; | |
if (contains(FileSystemRights.WriteAttributes, rule)) | |
_allowWriteAttributes = true; | |
if (contains(FileSystemRights.WriteData, rule)) | |
_allowWriteData = true; | |
if (contains(FileSystemRights.WriteExtendedAttributes, rule)) | |
_allowWriteExtendedAttributes = true; | |
} | |
} | |
} | |
System.Security.Principal.IdentityReferenceCollection groups = _principal.Groups; | |
for (int j = 0; j < groups.Count; j++) | |
{ | |
for (int i = 0; i < acl.Count; i++) | |
{ | |
System.Security.AccessControl.FileSystemAccessRule rule = | |
(System.Security.AccessControl.FileSystemAccessRule)acl[i]; | |
if (groups[j].Equals(rule.IdentityReference)) | |
{ | |
if (System.Security.AccessControl.AccessControlType. | |
Deny.Equals(rule.AccessControlType)) | |
{ | |
if (contains(FileSystemRights.AppendData, rule)) | |
_denyAppendData = true; | |
if (contains(FileSystemRights.ChangePermissions, rule)) | |
_denyChangePermissions = true; | |
if (contains(FileSystemRights.CreateDirectories, rule)) | |
_denyCreateDirectories = true; | |
if (contains(FileSystemRights.CreateFiles, rule)) | |
_denyCreateFiles = true; | |
if (contains(FileSystemRights.Delete, rule)) | |
_denyDelete = true; | |
if (contains(FileSystemRights. | |
DeleteSubdirectoriesAndFiles, rule)) | |
_denyDeleteSubdirectoriesAndFiles = true; | |
if (contains(FileSystemRights.ExecuteFile, rule)) | |
_denyExecuteFile = true; | |
if (contains(FileSystemRights.FullControl, rule)) | |
_denyFullControl = true; | |
if (contains(FileSystemRights.ListDirectory, rule)) | |
_denyListDirectory = true; | |
if (contains(FileSystemRights.Modify, rule)) | |
_denyModify = true; | |
if (contains(FileSystemRights.Read, rule)) | |
_denyRead = true; | |
if (contains(FileSystemRights.ReadAndExecute, rule)) | |
_denyReadAndExecute = true; | |
if (contains(FileSystemRights.ReadAttributes, rule)) | |
_denyReadAttributes = true; | |
if (contains(FileSystemRights.ReadData, rule)) | |
_denyReadData = true; | |
if (contains(FileSystemRights. | |
ReadExtendedAttributes, rule)) | |
_denyReadExtendedAttributes = true; | |
if (contains(FileSystemRights.ReadPermissions, rule)) | |
_denyReadPermissions = true; | |
if (contains(FileSystemRights.Synchronize, rule)) | |
_denySynchronize = true; | |
if (contains(FileSystemRights.TakeOwnership, rule)) | |
_denyTakeOwnership = true; | |
if (contains(FileSystemRights.Traverse, rule)) | |
_denyTraverse = true; | |
if (contains(FileSystemRights.Write, rule)) | |
_denyWrite = true; | |
if (contains(FileSystemRights.WriteAttributes, rule)) | |
_denyWriteAttributes = true; | |
if (contains(FileSystemRights.WriteData, rule)) | |
_denyWriteData = true; | |
if (contains(FileSystemRights. | |
WriteExtendedAttributes, rule)) | |
_denyWriteExtendedAttributes = true; | |
} | |
else if (System.Security.AccessControl.AccessControlType. | |
Allow.Equals(rule.AccessControlType)) | |
{ | |
if (contains(FileSystemRights.AppendData, rule)) | |
_allowAppendData = true; | |
if (contains(FileSystemRights.ChangePermissions, rule)) | |
_allowChangePermissions = true; | |
if (contains(FileSystemRights.CreateDirectories, rule)) | |
_allowCreateDirectories = true; | |
if (contains(FileSystemRights.CreateFiles, rule)) | |
_allowCreateFiles = true; | |
if (contains(FileSystemRights.Delete, rule)) | |
_allowDelete = true; | |
if (contains(FileSystemRights. | |
DeleteSubdirectoriesAndFiles, rule)) | |
_allowDeleteSubdirectoriesAndFiles = true; | |
if (contains(FileSystemRights.ExecuteFile, rule)) | |
_allowExecuteFile = true; | |
if (contains(FileSystemRights.FullControl, rule)) | |
_allowFullControl = true; | |
if (contains(FileSystemRights.ListDirectory, rule)) | |
_allowListDirectory = true; | |
if (contains(FileSystemRights.Modify, rule)) | |
_allowModify = true; | |
if (contains(FileSystemRights.Read, rule)) | |
_allowRead = true; | |
if (contains(FileSystemRights.ReadAndExecute, rule)) | |
_allowReadAndExecute = true; | |
if (contains(FileSystemRights.ReadAttributes, rule)) | |
_allowReadAttributes = true; | |
if (contains(FileSystemRights.ReadData, rule)) | |
_allowReadData = true; | |
if (contains(FileSystemRights. | |
ReadExtendedAttributes, rule)) | |
_allowReadExtendedAttributes = true; | |
if (contains(FileSystemRights.ReadPermissions, rule)) | |
_allowReadPermissions = true; | |
if (contains(FileSystemRights.Synchronize, rule)) | |
_allowSynchronize = true; | |
if (contains(FileSystemRights.TakeOwnership, rule)) | |
_allowTakeOwnership = true; | |
if (contains(FileSystemRights.Traverse, rule)) | |
_allowTraverse = true; | |
if (contains(FileSystemRights.Write, rule)) | |
_allowWrite = true; | |
if (contains(FileSystemRights.WriteAttributes, rule)) | |
_allowWriteAttributes = true; | |
if (contains(FileSystemRights.WriteData, rule)) | |
_allowWriteData = true; | |
if (contains(FileSystemRights.WriteExtendedAttributes, | |
rule)) _allowWriteExtendedAttributes = true; | |
} | |
} | |
} | |
} | |
} | |
catch (Exception e) | |
{ | |
//Deal with IO exceptions if you want | |
throw e; | |
} | |
} | |
/// <span class="code-SummaryComment"><summary> | |
/// Simply displays all allowed rights | |
/// | |
/// Useful if say you want to test for write access and find | |
/// it is false; | |
/// <xmp> | |
/// UserFileAccessRights rights = new UserFileAccessRights(txtLogPath.Text); | |
/// System.IO.FileInfo fi = new System.IO.FileInfo(txtLogPath.Text); | |
/// if (rights.canWrite() && rights.canRead()) { | |
/// lblLogMsg.Text = "R/W access"; | |
/// } else { | |
/// if (rights.canWrite()) { | |
/// lblLogMsg.Text = "Only Write access"; | |
/// } else if (rights.canRead()) { | |
/// lblLogMsg.Text = "Only Read access"; | |
/// } else { | |
/// lblLogMsg.CssClass = "error"; | |
/// lblLogMsg.Text = rights.ToString() | |
/// } | |
/// } | |
/// </xmp> | |
/// | |
/// </summary></span> | |
/// <span class="code-SummaryComment"><returns></returns></span> | |
public override String ToString() | |
{ | |
//string str = ""; | |
System.Text.StringBuilder str = new System.Text.StringBuilder(); | |
if (canAppendData()) | |
{ | |
if (str.Length > 0) str.Append(","); | |
str.Append("AppendData"); | |
} | |
if (canChangePermissions()) | |
{ | |
if (str.Length > 0) str.Append(","); | |
str.Append("ChangePermissions"); | |
} | |
if (canCreateDirectories()) | |
{ | |
if (str.Length > 0) str.Append(","); | |
str.Append("CreateDirectories"); | |
} | |
if (canCreateFiles()) | |
{ | |
if (str.Length > 0) str.Append(","); | |
str.Append("CreateFiles"); | |
} | |
if (canDelete()) | |
{ | |
if (str.Length > 0) str.Append(","); | |
str.Append("Delete"); | |
} | |
if (canDeleteSubdirectoriesAndFiles()) | |
{ | |
if (str.Length > 0) str.Append(","); | |
str.Append("DeleteSubdirectoriesAndFiles"); | |
} | |
if (canExecuteFile()) | |
{ | |
if (str.Length > 0) str.Append(","); | |
str.Append("ExecuteFile"); | |
} | |
if (canFullControl()) | |
{ | |
if (str.Length > 0) str.Append(","); | |
str.Append("FullControl"); | |
} | |
if (canListDirectory()) | |
{ | |
if (str.Length > 0) str.Append(","); | |
str.Append("ListDirectory"); | |
} | |
if (canModify()) | |
{ | |
if (str.Length > 0) str.Append(","); | |
str.Append("Modify"); | |
} | |
if (canRead()) | |
{ | |
if (str.Length > 0) str.Append(","); | |
str.Append("Read"); | |
} | |
if (canReadAndExecute()) | |
{ | |
if (str.Length > 0) str.Append(","); | |
str.Append("ReadAndExecute"); | |
} | |
if (canReadAttributes()) | |
{ | |
if (str.Length > 0) str.Append(","); | |
str.Append("ReadAttributes"); | |
} | |
if (canReadData()) | |
{ | |
if (str.Length > 0) str.Append(","); | |
str.Append("ReadData"); | |
} | |
if (canReadExtendedAttributes()) | |
{ | |
if (str.Length > 0) str.Append(","); | |
str.Append("ReadExtendedAttributes"); | |
} | |
if (canReadPermissions()) | |
{ | |
if (str.Length > 0) str.Append(","); | |
str.Append("ReadPermissions"); | |
} | |
if (canSynchronize()) | |
{ | |
if (str.Length > 0) str.Append(","); | |
str.Append("Synchronize"); | |
} | |
if (canTakeOwnership()) | |
{ | |
if (str.Length > 0) str.Append(","); | |
str.Append("TakeOwnership"); | |
} | |
if (canTraverse()) | |
{ | |
if (str.Length > 0) str.Append(","); | |
str.Append("Traverse"); | |
} | |
if (canWrite()) | |
{ | |
if (str.Length > 0) str.Append(","); | |
str.Append("Write"); | |
} | |
if (canWriteAttributes()) | |
{ | |
if (str.Length > 0) str.Append(","); | |
str.Append("WriteAttributes"); | |
} | |
if (canWriteData()) | |
{ | |
if (str.Length > 0) str.Append(","); | |
str.Append("WriteData"); | |
} | |
if (canWriteExtendedAttributes()) | |
{ | |
if (str.Length > 0) str.Append(","); | |
str.Append("WriteExtendedAttributes"); | |
} | |
if (str.Length > 0) | |
str.Append("None"); | |
return str.ToString(); | |
} | |
/// <span class="code-SummaryComment"><summary> | |
/// Convenience method to test if the right exists within the given rights | |
/// </summary></span> | |
/// <span class="code-SummaryComment"><param name="right"></param></span> | |
/// <span class="code-SummaryComment"><param name="rule"></param></span> | |
/// <span class="code-SummaryComment"><returns></returns></span> | |
public bool contains(System.Security.AccessControl.FileSystemRights right, | |
System.Security.AccessControl.FileSystemAccessRule rule) | |
{ | |
return (((int)right & (int)rule.FileSystemRights) == (int)right); | |
} | |
public static string FindFirstFailingPath(string path) | |
{ | |
// Could use bisect to improve performance. | |
var chars = new char[] { '\\', '/' }; | |
var segments = path.Split(chars); | |
var aggregate = ""; | |
foreach (var segment in segments) | |
{ | |
aggregate += segment + '\\'; | |
try | |
{ | |
var dummy = new UserFileAccessRights(aggregate); | |
} | |
catch (Exception e) | |
{ | |
break; // Found failing path | |
} | |
} | |
return aggregate; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment