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.
 
 

321 line
12 KiB

  1. using System.Management.Automation;
  2. using Security2;
  3. using ProcessPrivileges;
  4. using System.Linq;
  5. using System.Collections.Generic;
  6. using System;
  7. using System.Collections;
  8. namespace NTFSSecurity
  9. {
  10. public class BaseCmdlet : PSCmdlet
  11. {
  12. protected List<string> paths = new List<string>();
  13. protected List<FileSystemSecurity2> securityDescriptors = new List<FileSystemSecurity2>();
  14. protected override void BeginProcessing()
  15. {
  16. base.BeginProcessing();
  17. }
  18. protected override void ProcessRecord()
  19. {
  20. base.ProcessRecord();
  21. }
  22. #region GetFileSystemInfo
  23. protected System.IO.FileSystemInfo GetFileSystemInfo(string path)
  24. {
  25. string currentLocation = GetVariableValue("PWD").ToString();
  26. if (path == ".")
  27. {
  28. path = currentLocation;
  29. }
  30. if (path.StartsWith(".."))
  31. {
  32. path = System.IO.Path.Combine(
  33. string.Join("\\", currentLocation.Split('\\').Take(currentLocation.Split('\\').Count() - path.Split('\\').Count(s => s == "..")).ToArray()),
  34. string.Join("\\", path.Split('\\').Where(e => e != "..").ToArray()));
  35. }
  36. else if (path.StartsWith("."))
  37. {
  38. //combine . and .\path\subpath
  39. path = System.IO.Path.Combine(currentLocation, path.Substring(2));
  40. }
  41. else if (path.StartsWith("\\"))
  42. {
  43. //do nothing
  44. }
  45. else
  46. {
  47. ////combine . and \path\subpath or path\subpath
  48. path = System.IO.Path.Combine(currentLocation, path.Substring(0));
  49. }
  50. if (System.IO.File.Exists(path))
  51. {
  52. return new System.IO.FileInfo(path);
  53. }
  54. else if (System.IO.Directory.Exists(path))
  55. {
  56. return new System.IO.DirectoryInfo(path);
  57. }
  58. else
  59. {
  60. throw new System.IO.FileNotFoundException();
  61. }
  62. }
  63. #endregion
  64. #region GetFileSystemInfo2
  65. protected Alphaleonis.Win32.Filesystem.FileSystemInfo GetFileSystemInfo2(string path)
  66. {
  67. path = GetRelativePath(path);
  68. if (Alphaleonis.Win32.Filesystem.File.Exists(path))
  69. {
  70. return new Alphaleonis.Win32.Filesystem.FileInfo(path);
  71. }
  72. else if (Alphaleonis.Win32.Filesystem.Directory.Exists(path))
  73. {
  74. return new Alphaleonis.Win32.Filesystem.DirectoryInfo(path);
  75. }
  76. else
  77. {
  78. throw new System.IO.FileNotFoundException();
  79. }
  80. }
  81. #endregion
  82. #region TryGetFileSystemInfo2
  83. protected bool TryGetFileSystemInfo2(string path, out Alphaleonis.Win32.Filesystem.FileSystemInfo item)
  84. {
  85. path = GetRelativePath(path);
  86. item = null;
  87. if (Alphaleonis.Win32.Filesystem.File.Exists(path))
  88. {
  89. item = new Alphaleonis.Win32.Filesystem.FileInfo(path);
  90. }
  91. else if (Alphaleonis.Win32.Filesystem.Directory.Exists(path))
  92. {
  93. item = new Alphaleonis.Win32.Filesystem.DirectoryInfo(path);
  94. }
  95. else
  96. {
  97. return false;
  98. }
  99. return true;
  100. }
  101. #endregion
  102. #region GetRelativePath
  103. protected string GetRelativePath(string path)
  104. {
  105. string currentLocation = GetVariableValue("PWD").ToString();
  106. if (string.IsNullOrEmpty(path))
  107. {
  108. path = currentLocation;
  109. }
  110. else if (path == ".")
  111. {
  112. path = currentLocation;
  113. }
  114. else if (path.StartsWith(".."))
  115. {
  116. path = System.IO.Path.Combine(
  117. string.Join("\\", currentLocation.Split('\\').Take(currentLocation.Split('\\').Count() - path.Split('\\').Count(s => s == "..")).ToArray()),
  118. string.Join("\\", path.Split('\\').Where(e => e != "..").ToArray()));
  119. }
  120. else if (path.StartsWith("."))
  121. {
  122. //combine . and .\path\subpath
  123. path = System.IO.Path.Combine(currentLocation, path.Substring(2));
  124. }
  125. else if (path.StartsWith("\\"))
  126. {
  127. //do nothing
  128. }
  129. else
  130. {
  131. ////combine . and \path\subpath or path\subpath
  132. path = System.IO.Path.Combine(currentLocation, path);
  133. }
  134. return path;
  135. }
  136. #endregion
  137. }
  138. public class BaseCmdletWithPrivControl : BaseCmdlet
  139. {
  140. protected PrivilegeAndAttributesCollection privileges = null;
  141. protected PrivilegeControl privControl = new PrivilegeControl();
  142. private List<string> enabledPrivileges = new List<string>();
  143. Hashtable privateData = null;
  144. protected override void BeginProcessing()
  145. {
  146. privateData = (Hashtable)MyInvocation.MyCommand.Module.PrivateData;
  147. if ((bool)privateData["EnablePrivileges"])
  148. {
  149. WriteVerbose("EnablePrivileges enabled in PrivateDate");
  150. EnableFileSystemPrivileges(true);
  151. }
  152. }
  153. protected override void EndProcessing()
  154. {
  155. if ((bool)privateData["EnablePrivileges"])
  156. {
  157. WriteVerbose("EnablePrivileges enabled in PrivateDate");
  158. //disable all privileges that have been enabled by this cmdlet
  159. WriteVerbose(string.Format("Disabeling all {0} enabled privileges...", enabledPrivileges.Count));
  160. foreach (var privilege in enabledPrivileges)
  161. {
  162. DisablePrivilege((Privilege)Enum.Parse(typeof(Privilege), privilege));
  163. WriteVerbose(string.Format("\t{0} disabled", privilege));
  164. }
  165. WriteVerbose(string.Format("...finished"));
  166. }
  167. }
  168. protected void EnablePrivilege(Privilege privilege)
  169. {
  170. //throw an exception if the specified prililege is not held by the client
  171. if (!privileges.Any(p => p.Privilege == privilege))
  172. throw new System.Security.AccessControl.PrivilegeNotHeldException(privilege.ToString());
  173. //if the privilege is disabled
  174. if (privileges.Single(p => p.Privilege == privilege).PrivilegeState == PrivilegeState.Disabled)
  175. {
  176. WriteDebug(string.Format("The privilege {0} is disabled...", privilege));
  177. //activate it
  178. privControl.EnablePrivilege(privilege);
  179. WriteDebug(string.Format("..enabled"));
  180. //remember the privilege so that we can automatically disable it after the cmdlet finished processing
  181. enabledPrivileges.Add(privilege.ToString());
  182. privileges = privControl.GetPrivileges();
  183. }
  184. }
  185. public void DisablePrivilege(Privilege privilege)
  186. {
  187. //if the privilege is enabled
  188. if (privileges.Single(p => p.Privilege == privilege).PrivilegeState == PrivilegeState.Enabled)
  189. privControl.DisablePrivilege(privilege);
  190. }
  191. protected bool TryEnablePrivilege(Privilege privilege)
  192. {
  193. try
  194. {
  195. EnablePrivilege(privilege);
  196. return true;
  197. }
  198. catch(Exception ex)
  199. {
  200. WriteDebug(string.Format("Could not enable privilege {0}. The error was: {1}", privilege, ex.Message));
  201. return false;
  202. }
  203. }
  204. protected bool TryDisablePrivilege(Privilege privilege)
  205. {
  206. try
  207. {
  208. DisablePrivilege(privilege);
  209. return true;
  210. }
  211. catch
  212. {
  213. WriteDebug(string.Format("Could not disable privilege {0}.", privilege));
  214. return false;
  215. }
  216. }
  217. protected void EnableFileSystemPrivileges(bool quite = true)
  218. {
  219. privileges = (new PrivilegeControl()).GetPrivileges();
  220. if (!TryEnablePrivilege(Privilege.TakeOwnership))
  221. WriteDebug("The privilige 'TakeOwnership' could not be enabled. Make sure your user account does have this privilige");
  222. if (!TryEnablePrivilege(Privilege.Restore))
  223. WriteDebug("The privilige 'Restore' could not be enabled. Make sure your user account does have this privilige");
  224. if (!TryEnablePrivilege(Privilege.Backup))
  225. WriteDebug("The privilige 'Backup' could not be enabled. Make sure your user account does have this privilige");
  226. if (!TryEnablePrivilege(Privilege.Security))
  227. WriteDebug("The privilige 'Security' could not be enabled. Make sure your user account does have this privilige");
  228. if (!quite)
  229. {
  230. if (privControl.GetPrivileges()
  231. .Where(p => p.PrivilegeState == PrivilegeState.Enabled)
  232. .Where(p =>
  233. (p.Privilege == Privilege.TakeOwnership) |
  234. (p.Privilege == Privilege.Restore) |
  235. (p.Privilege == Privilege.Backup) |
  236. (p.Privilege == Privilege.Security)).Count() == 4)
  237. {
  238. WriteVerbose("The privileges 'Backup', 'Restore', 'TakeOwnership' and 'Security' are now enabled giving you access to all files and folders. Use Disable-Privileges to disable them and Get-Privileges for an overview.");
  239. }
  240. else
  241. {
  242. WriteError(new ErrorRecord(new AdjustPriviledgeException("Could not enable requested privileges. Cmdlets of NTFSSecurity will only work on resources you have access to."), "Enable Privilege Error", ErrorCategory.SecurityError, null));
  243. return;
  244. }
  245. }
  246. }
  247. protected void DisableFileSystemPrivileges()
  248. {
  249. var privileges = privControl.GetPrivileges();
  250. if (privileges.Where(p => p.Privilege == Privilege.TakeOwnership) != null)
  251. if (!TryDisablePrivilege(Privilege.TakeOwnership))
  252. WriteWarning("The privilige 'TakeOwnership' could not be disabled.");
  253. else
  254. WriteDebug("The privilige 'TakeOwnership' was disabled.");
  255. if (privileges.Where(p => p.Privilege == Privilege.Restore) != null)
  256. if (!TryDisablePrivilege(Privilege.Restore))
  257. WriteWarning("The privilige 'Restore' could not be disabled.");
  258. else
  259. WriteDebug("The privilige 'Restore' was disabled.");
  260. if (privileges.Where(p => p.Privilege == Privilege.Backup) != null)
  261. if (!TryDisablePrivilege(Privilege.Backup))
  262. WriteWarning("The privilige 'Backup' could not be disabled.");
  263. else
  264. WriteDebug("The privilige 'Backup' was disabled.");
  265. if (!TryDisablePrivilege(Privilege.Security))
  266. WriteWarning("The privilige 'Security' could not be disabled.");
  267. else
  268. WriteDebug("The privilige 'Security' was disabled.");
  269. }
  270. protected void WriteWarning(string text, params string[] args)
  271. {
  272. base.WriteWarning(string.Format(text, args));
  273. }
  274. protected void WriteVerbose(string text, params string[] args)
  275. {
  276. base.WriteVerbose(string.Format(text, args));
  277. }
  278. protected void WriteDebug(string text, params string[] args)
  279. {
  280. base.WriteDebug(string.Format(text, args));
  281. }
  282. }
  283. }