You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

194 lines
8.3 KiB

  1. using Alphaleonis.Win32.Filesystem;
  2. using ProcessPrivileges;
  3. using Security2;
  4. using System;
  5. using System.Collections.Generic;
  6. using System.Linq;
  7. using System.Management.Automation;
  8. namespace NTFSSecurity
  9. {
  10. [Cmdlet(VerbsCommon.Get, "NTFSEffectiveAccess", DefaultParameterSetName = "Path")]
  11. [OutputType(typeof(FileSystemAccessRule2))]
  12. public class GetEffectiveAccess : BaseCmdletWithPrivControl
  13. {
  14. private IdentityReference2 account = System.Security.Principal.WindowsIdentity.GetCurrent().User.Value;
  15. private SwitchParameter excludeNoneAccessEntries;
  16. private string serverName = "localhost";
  17. private IEnumerable<PrivilegeAndAttributes> securityPrivilege;
  18. [Parameter(Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = "Path")]
  19. [ValidateNotNullOrEmpty]
  20. [Alias("FullName")]
  21. public string[] Path
  22. {
  23. get { return paths.ToArray(); }
  24. set
  25. {
  26. paths.Clear();
  27. paths.AddRange(value);
  28. }
  29. }
  30. [Parameter(Mandatory = true, Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = "SecurityDescriptor")]
  31. [ValidateNotNullOrEmpty]
  32. public FileSystemSecurity2[] SecurityDescriptor
  33. {
  34. get { return securityDescriptors.ToArray(); }
  35. set
  36. {
  37. securityDescriptors.Clear();
  38. securityDescriptors.AddRange(value);
  39. }
  40. }
  41. [Parameter(Position = 2, ValueFromPipelineByPropertyName = true)]
  42. [Alias("NTAccount", "IdentityReference")]
  43. [ValidateNotNullOrEmpty]
  44. public IdentityReference2 Account
  45. {
  46. get { return account; }
  47. set { account = value; }
  48. }
  49. [Parameter]
  50. public string ServerName
  51. {
  52. get { return serverName; }
  53. set { serverName = value; }
  54. }
  55. [Parameter()]
  56. public SwitchParameter ExcludeNoneAccessEntries
  57. {
  58. get { return excludeNoneAccessEntries; }
  59. set { excludeNoneAccessEntries = value; }
  60. }
  61. protected override void BeginProcessing()
  62. {
  63. base.BeginProcessing();
  64. if (paths == null)
  65. {
  66. paths = new List<string>() { GetVariableValue("PWD").ToString() };
  67. }
  68. var securityPrivilege = privControl.GetPrivileges().Where(priv => priv.Privilege == ProcessPrivileges.Privilege.Security);
  69. if (securityPrivilege.Count() == 0)
  70. {
  71. this.WriteWarning("The user does not hold the Security Privliege and might not be able to read the effective permissions");
  72. }
  73. else
  74. {
  75. if (securityPrivilege.FirstOrDefault().PrivilegeState == PrivilegeState.Disabled)
  76. {
  77. this.WriteWarning("The user does hold the Security Privilege but it is disabled. Hence getting effective permissions might not be possible. Use 'Enable-Privileges' to enable it");
  78. }
  79. }
  80. }
  81. protected override void ProcessRecord()
  82. {
  83. FileSystemInfo item = null;
  84. foreach (var path in paths)
  85. {
  86. EffectiveAccessInfo result = null;
  87. try
  88. {
  89. item = this.GetFileSystemInfo2(path);
  90. }
  91. catch (Exception ex)
  92. {
  93. this.WriteError(new ErrorRecord(ex, "ReadFileError", ErrorCategory.OpenError, path));
  94. continue;
  95. }
  96. try
  97. {
  98. result = EffectiveAccess.GetEffectiveAccess(item, account, serverName);
  99. if (!result.FromRemote)
  100. {
  101. WriteWarning("The effective rights can only be computed based on group membership on this" +
  102. " computer. For more accurate results, calculate effective access rights on " +
  103. "the target computer");
  104. }
  105. if (result.OperationFailed && securityPrivilege == null)
  106. {
  107. var ex = new Exception(string.Format("Could not get effective permissions from machine '{0}' maybe because the 'Security' privilege is not enabled which might be required. Enable the priviliges using 'Enable-Privileges'. The error was '{1}'", serverName, result.AuthzException.Message), result.AuthzException);
  108. WriteError(new ErrorRecord(ex, "GetEffectiveAccessError", ErrorCategory.ReadError, item));
  109. continue;
  110. }
  111. else if (result.OperationFailed)
  112. {
  113. var ex = new Exception(string.Format("Could not get effective permissions from machine '{0}'. The error is '{1}'", serverName, result.AuthzException.Message), result.AuthzException);
  114. WriteError(new ErrorRecord(ex, "GetEffectiveAccessError", ErrorCategory.ReadError, item));
  115. continue;
  116. }
  117. if (excludeNoneAccessEntries && result.Ace.AccessRights == FileSystemRights2.None)
  118. continue;
  119. }
  120. //not sure if the following catch block willb be invoked, testing needed.
  121. catch (UnauthorizedAccessException)
  122. {
  123. try
  124. {
  125. var ownerInfo = FileSystemOwner.GetOwner(item);
  126. var previousOwner = ownerInfo.Owner;
  127. FileSystemOwner.SetOwner(item, System.Security.Principal.WindowsIdentity.GetCurrent().User);
  128. //--------------------
  129. result = EffectiveAccess.GetEffectiveAccess(item, account, serverName);
  130. if (!result.FromRemote)
  131. {
  132. WriteWarning("The effective rights can only be computed based on group membership on this" +
  133. " computer. For more accurate results, calculate effective access rights on " +
  134. "the target computer");
  135. }
  136. if (result.OperationFailed && securityPrivilege == null)
  137. {
  138. var ex = new Exception(string.Format("Could not get effective permissions from machine '{0}' maybe because the 'Security' privilege is not enabled which might be required. Enable the priviliges using 'Enable-Privileges'. The error was '{1}'", serverName, result.AuthzException.Message), result.AuthzException);
  139. WriteError(new ErrorRecord(ex, "GetEffectiveAccessError", ErrorCategory.ReadError, item));
  140. continue;
  141. }
  142. else if (result.OperationFailed)
  143. {
  144. var ex = new Exception(string.Format("Could not get effective permissions from machine '{0}'. The error is '{1}'", serverName, result.AuthzException.Message), result.AuthzException);
  145. WriteError(new ErrorRecord(ex, "GetEffectiveAccessError", ErrorCategory.ReadError, item));
  146. continue;
  147. }
  148. if (excludeNoneAccessEntries && result.Ace.AccessRights == FileSystemRights2.None)
  149. continue;
  150. //--------------------
  151. FileSystemOwner.SetOwner(item, previousOwner);
  152. }
  153. catch (Exception ex2)
  154. {
  155. this.WriteError(new ErrorRecord(ex2, "ReadSecurityError", ErrorCategory.WriteError, path));
  156. }
  157. }
  158. catch (Exception ex)
  159. {
  160. WriteError(new ErrorRecord(ex, "ReadEffectivePermissionError", ErrorCategory.ReadError, path));
  161. }
  162. finally
  163. {
  164. if (result != null)
  165. {
  166. WriteObject(result.Ace);
  167. }
  168. }
  169. }
  170. }
  171. }
  172. }