続 Vistaで特定のファイル名のついた実行ファイルの実行に管理者権限が必要な件

前回(id:yaneurao:20071015)の続き。


うちの会社で作ったオンラインゲームのオンラインアップデートをするためのプログラム(以下、アップデータと呼ぶ)にupdateという名前をつけてしまったがためにUACが必要になっていたよ、というのが前回までの話。


前回書いたようにファイルをリネームするか、アプリケーションマニフェストを書けば*1これ自体は回避できるので知っていればたいした問題ではないように思えるが、そうでもない。*2

UACによる仮想化では,ファイル・アクセスの場合,%SystemRoot%,%ProgramData%,%ProgramFiles%へのアクセスが仮想化され,%LoadlAppData%\VirtualStoreにリダイレクトされる(図2)。ただし例外もあり,*.exe,*.dll,*.sysの書き込みについては,アプリケーションのインストールと判断し仮想化によって互換性を確保するのではなく,管理者権限を求め,元のフォルダに書き込むようになっている。


UACによる権限の制限がユーザーを守る
Windows Vista Security IN & OUT
事件と課題から考えるWindows Vistaのセキュリティ(第8回)
http://itpro.nikkeibp.co.jp/article/COLUMN/20071002/283617/

要するに、アップデータが*.dllや*.exeというファイルをVirtualStoreに書き込めず、インストール先のフォルダに書き込みしに行こうとするのだが、管理者権限で実行されていないアップデータはそこで失敗する。


アップデータはインストール先のフォルダに書き込みに行く代わりにEnvironment.SpecialFolder.ApplicationDataなどのフォルダに書き込みに行くか、インストールのときにeveryoneが書き込めるフォルダを作成してしまいアップデータはそこに書き込みに行けばいいと思う。


インストール先以外のフォルダに書き込みに行くのはちょっと気持ち悪い気もするので私は後者で対応することにした。


Network Serviceアカウントに適切な権限を付加する
http://csharper.blog57.fc2.com/?tag=%A5%A4%A5%F3%A5%B9%A5%C8%A1%BC%A5%E9


new FileSystemAccessRule("NT AUTHORITY\\NETWORK SERVICE",
FileSystemRights.Write, AccessControlType.Allow);

この部分の第一引数を "\\Everyone" とか "BUILTIN\Users" とかにしてしまえば良いだろう。


Everyoneがフルコントロール出来ては、何のためにProgramFilesを管理者しか書き込めなくしてるんだという気もするが、現実的にはそうそう問題が起きるわけでもないだろうから、これでいいと思う。

*1:UAC (User Account Control) と C/C++ MFC アプリケーション(その2)
http://bitwiz.jp/tabid/56/EntryID/19/Default.aspx

*2:ちなみにアプリケーションマニフェストでrequestedExecutionLevelタグを何かしら指定すると、Vistaに対応してると見なされて、仮想化(VirtualStoreなど)が働かなくなる。この動作がまずいなら、下手にアプリケーションマニフェストを使うべきではない。