From dafecd86da319b749d0e8b635767a59914ea6dc2 Mon Sep 17 00:00:00 2001 From: Yoshi Askharoun Date: Mon, 15 Aug 2022 18:09:53 -0500 Subject: [PATCH] Switched TokenManipulator to Vanara.PInvoke libraries --- ZuneModCore/Win32/TokenManipulator.cs | 101 ++++++++++++++------------ ZuneModCore/ZuneModCore.csproj | 3 + 2 files changed, 58 insertions(+), 46 deletions(-) diff --git a/ZuneModCore/Win32/TokenManipulator.cs b/ZuneModCore/Win32/TokenManipulator.cs index b9bb82f..a0146d5 100644 --- a/ZuneModCore/Win32/TokenManipulator.cs +++ b/ZuneModCore/Win32/TokenManipulator.cs @@ -3,47 +3,27 @@ using System.IO; using System.Runtime.InteropServices; using System.Security.AccessControl; using System.Security.Principal; +using Vanara.PInvoke; namespace ZuneModCore.Win32 { public class TokenManipulator { - [DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)] - internal static extern bool AdjustTokenPrivileges(IntPtr htok, bool disall, - ref TokPriv1Luid newst, int len, IntPtr prev, IntPtr relen); - [DllImport("kernel32.dll", ExactSpelling = true)] - internal static extern IntPtr GetCurrentProcess(); - [DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)] - internal static extern bool OpenProcessToken(IntPtr h, int acc, ref IntPtr - phtok); - [DllImport("advapi32.dll", SetLastError = true)] - internal static extern bool LookupPrivilegeValue(string host, string name, - ref long pluid); - [StructLayout(LayoutKind.Sequential, Pack = 1)] - internal struct TokPriv1Luid - { - public int Count; - public long Luid; - public int Attr; - } - internal const int SE_PRIVILEGE_DISABLED = 0x00000000; - internal const int SE_PRIVILEGE_ENABLED = 0x00000002; - internal const int TOKEN_QUERY = 0x00000008; - internal const int TOKEN_ADJUST_PRIVILEGES = 0x00000020; public static bool AddPrivilege(string privilege) { try { bool retVal; - TokPriv1Luid tp; - IntPtr hproc = GetCurrentProcess(); - IntPtr htok = IntPtr.Zero; - retVal = OpenProcessToken(hproc, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, ref htok); - tp.Count = 1; - tp.Luid = 0; - tp.Attr = SE_PRIVILEGE_ENABLED; - retVal = LookupPrivilegeValue(null, privilege, ref tp.Luid); - retVal = AdjustTokenPrivileges(htok, false, ref tp, 0, IntPtr.Zero, IntPtr.Zero); + var hproc = Kernel32.GetCurrentProcess(); + + retVal = AdvApi32.OpenProcessToken(hproc, + AdvApi32.TokenAccess.TOKEN_ADJUST_PRIVILEGES | AdvApi32.TokenAccess.TOKEN_QUERY, out var htok); + + retVal = AdvApi32.LookupPrivilegeValue(null, privilege, out var tpLuid); + AdvApi32.TOKEN_PRIVILEGES tp = new(tpLuid, AdvApi32.PrivilegeAttributes.SE_PRIVILEGE_ENABLED); + + AdvApi32.AdjustTokenPrivileges(htok, false, in tp, out _).ThrowIfFailed(); + return retVal; } catch @@ -56,15 +36,16 @@ namespace ZuneModCore.Win32 try { bool retVal; - TokPriv1Luid tp; - IntPtr hproc = GetCurrentProcess(); - IntPtr htok = IntPtr.Zero; - retVal = OpenProcessToken(hproc, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, ref htok); - tp.Count = 1; - tp.Luid = 0; - tp.Attr = SE_PRIVILEGE_DISABLED; - retVal = LookupPrivilegeValue(null, privilege, ref tp.Luid); - retVal = AdjustTokenPrivileges(htok, false, ref tp, 0, IntPtr.Zero, IntPtr.Zero); + var hproc = Kernel32.GetCurrentProcess(); + + retVal = AdvApi32.OpenProcessToken(hproc, + AdvApi32.TokenAccess.TOKEN_ADJUST_PRIVILEGES | AdvApi32.TokenAccess.TOKEN_QUERY, out var htok); + + retVal = AdvApi32.LookupPrivilegeValue(null, privilege, out var tpLuid); + AdvApi32.TOKEN_PRIVILEGES tp = new(tpLuid, AdvApi32.PrivilegeAttributes.SE_PRIVILEGE_DISABLED); + + AdvApi32.AdjustTokenPrivileges(htok, false, in tp, out _).ThrowIfFailed(); + return retVal; } catch @@ -76,10 +57,7 @@ namespace ZuneModCore.Win32 #pragma warning disable CA1416 // Validate platform compatibility public static void TakeOwnership(FileInfo file) { - // Activate necessary admin privileges to make changes without NTFS perms - AddPrivilege("SeRestorePrivilege"); // Necessary to set Owner Permissions - AddPrivilege("SeBackupPrivilege"); // Necessary to bypass Traverse Checking - AddPrivilege("SeTakeOwnershipPrivilege"); // Necessary to override FilePermissions + EscalateToAdmin(); // Get access control FileSecurity security = file.GetAccessControl(); @@ -89,11 +67,34 @@ namespace ZuneModCore.Win32 security.SetOwner(cu); security.SetAccessRule(new FileSystemAccessRule(cu, FileSystemRights.Modify, AccessControlType.Allow)); - // Update the Access Control on the original WMVCORE.dll + // Update the Access Control on the original file file.SetAccessControl(security); } -#pragma warning restore CA1416 // Validate platform compatibility + public static void TakeOwnership(DirectoryInfo dir) + { + EscalateToAdmin(); + + // Get access control + DirectorySecurity security = dir.GetAccessControl(); + SecurityIdentifier? cu = WindowsIdentity.GetCurrent().User; + + // Set owner to current user + security.SetOwner(cu); + security.SetAccessRule(new FileSystemAccessRule(cu, FileSystemRights.Modify, AccessControlType.Allow)); + + // Update the Access Control on the original file + dir.SetAccessControl(security); + } + + public static void TakeOwnership(FileSystemInfo info) + { + if (info is FileInfo file) + TakeOwnership(file); + else if (info is DirectoryInfo dir) + TakeOwnership(dir); + } +#pragma warning restore CA1416 // Validate platform compatibility public static bool TryTakeOwnership(FileInfo file, out Exception? exception) { @@ -110,5 +111,13 @@ namespace ZuneModCore.Win32 return false; } } + + public static void EscalateToAdmin() + { + // Activate necessary admin privileges to make changes without NTFS perms + AddPrivilege("SeRestorePrivilege"); // Necessary to set Owner Permissions + AddPrivilege("SeBackupPrivilege"); // Necessary to bypass Traverse Checking + AddPrivilege("SeTakeOwnershipPrivilege"); // Necessary to override FilePermissions + } } } diff --git a/ZuneModCore/ZuneModCore.csproj b/ZuneModCore/ZuneModCore.csproj index 4f3daa8..c68bc17 100644 --- a/ZuneModCore/ZuneModCore.csproj +++ b/ZuneModCore/ZuneModCore.csproj @@ -5,6 +5,7 @@ 9 enable AnyCPU;x64;x86 + true @@ -12,6 +13,8 @@ + +