#実現したいこと
ファイルの所有者を変更して、アクセス権を変更しようと思っています。
現在のユーザーアカウントのファイルの所有権をAdministratorsに変更し、ファイルのアクセス権を変更することができました。
しかし、ファイルの所有者がTrustedInstallerの場合はうまくいきませんでしたので
visualstudioは管理者権限で起動しています。
ネットで検索してみると、
ファイルの所有者がTrusted Installerの場合はPrivelegeのクラスを用意しなければならないらしいので、以下のように実装しました。(ファイルの所有者を変更するところまで記載しています。)
using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Security.AccessControl; using System.Security.Principal; using System.Text; using System.Threading.Tasks; using System.Windows; public class ModifyPermission { public static bool DenyFileAccess(string filepath) { FileSecurity fs; fs = File.GetAccessControl(filepath); var ntAccount = new NTAccount("BUILTIN", "Administrators"); fs.SetOwner(ntAccount); Privilege p; bool ownerChanged = false; try { p = new Privilege(Privilege.TakeOwnership); p.Enable(); fs.SetOwner(new System.Security.Principal.NTAccount( Environment.UserDomainName, Environment.UserName)); ownerChanged = true; } catch (PrivilegeNotHeldException e) { // privilege not held // TODO: show an error message, write logs, etc. } finally { p.Revert(); } if (!ownerChanged) return false; try { File.SetAccessControl(filepath, fs); } catch (InvalidOperationException ex) { //Debug.WriteLine("You cannot assign ownership to that user." + // "Either you don't have TakeOwnership permissions, or it is not your user account." //); //throw; return false; } catch(System.UnauthorizedAccessException e3) { MessageBox.Show("error"); } //以下省略 } }
すると、
Privelegeはアクセスできない保護レベルですといわれましたとエラーがはかれました。
Privelegeの定義へ移動すると
internal sealed class privilegeとなっていました。
今回の自作クラスは継承をしていないので、internalに問題があるかと思い、
AssemblyInfo.csに
[assembly: InternalsVisibleTo("System.Security.AccessControl")]
を追加しました。しかしエラーが出たままです。
上の属性の文字列の部分に該当の名前空間を入れたはずなのですが、エラーが出たままでした。
どこをどのように修正すれば、エラーが払えるでしょうか。
回答お願いします。
##環境
windows10 pro 1803
visualstudio 2017
##追記2
System.Reflectionを使用して実装しました。
例外を投げずに処理ができたのですが、
ファイルのアクセス権および所有者は変更されませんでした。
下記のサイトを参考にしました。
https://stackoverflow.com/questions/5528888/how-to-enable-the-secreateglobalprivilege-in-net-without-resorting-to-p-invoke?lq=1
public static bool DenyFileAccess(string filepath) { FileSecurity fs; fs = File.GetAccessControl(filepath); Type privilegeType = Type.GetType("System.Security.AccessControl.Privilege"); object privilege; bool ownerChanged = false; try { privilege = Activator.CreateInstance(privilegeType, "SeTakeOwnershipPrivilege"); // => privilege.Enable(); privilegeType.GetMethod("Enable").Invoke(privilege, null); var ntAccount = new NTAccount("BUILTIN", "Administrators"); fs.SetOwner(ntAccount); File.SetAccessControl(filepath, fs); privilegeType.GetMethod("Revert").Invoke(privilege, null); ownerChanged = true; } catch { MessageBox.Show("error"); } if (!ownerChanged) return false; try { File.SetAccessControl(filepath, fs); } catch (InvalidOperationException ex) { MessageBox.Show("error"); return false; } catch (System.UnauthorizedAccessException e3) { MessageBox.Show("error"); } try { Debug.WriteLine("Adding access control entry for " + filepath); //管理者権限で起動していても、デスクトップユーザーのアカウント名が返されます。nuget->Cassia ITerminalServicesManager manager = new TerminalServicesManager(); ITerminalServicesSession session = manager.CurrentSession; string username = session.UserName; // Add the access control entry to the file. string principal = string.Format(@"{0}\{1}", System.Environment.MachineName, username); AddFileSecurity(filepath, principal, FileSystemRights.ReadAndExecute, AccessControlType.Deny); AddFileSecurity(filepath, principal, FileSystemRights.Read, AccessControlType.Deny); //Console.WriteLine("Removing access control entry from " // + filepath); //// Remove the access control entry from the file. //RemoveFileSecurity(filepath, @"BUILTIN\Administrators", // FileSystemRights.ReadData, AccessControlType.Allow); Console.WriteLine("Done."); } catch (System.UnauthorizedAccessException e3) { MessageBox.Show("error"); } catch (Exception e2) { Console.WriteLine(e2); return false; }
##追記3
方法2
static class Program { [STAThread] static void Main() { string filepath = @"C:\WINDOWS\system32\cmd.exe"; FileSecurity fs; fs = File.GetAccessControl(filepath); var takeOwnerShip = new Privirage(PrivirageNames.SeTakeOwnershipPrivilege); takeOwnerShip.Enable(); ProcessStartInfo psi = new ProcessStartInfo("whoami.exe", "/priv") { UseShellExecute = false }; using (Process pprocess = Process.Start(psi)) { pprocess.WaitForExit(); } var ntAccount = new NTAccount("BUILTIN", "Administrators"); fs.SetOwner(ntAccount); File.SetAccessControl(filepath, fs); takeOwnerShip.Revert(); psi = new ProcessStartInfo("whoami.exe", "/priv") { UseShellExecute = false }; using (Process pprocess = Process.Start(psi)) { pprocess.WaitForExit(); } Console.ReadKey(); } }
回答3件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/07/26 15:59
2019/07/27 00:13 編集
2019/07/27 02:46 編集
2019/07/27 07:16 編集
2019/07/27 14:54
2019/07/27 15:42