■Windows XPでは,すべてのリソースをオブジェクトとしてとらえるオブジェクト指向のプログラム技術を採用している。ファイルやフォルダはもちろん,ソフトウエアやプリンタなども,すべてオブジェクトとして扱われる。
■あるオブジェクトが別のオブジェクトにアクセスするプロセスは,セキュリティ参照モニターによって監視されている。アクセスするオブジェクトが持つ「アクセス・トークン」と,アクセスされるオブジェクトが備える「セキュリティ記述子」を照合し,アクセス権があるかどうかを調べている。

(2006年1月号「本当に知っている?Windows XPの基礎[アーキテクチャ編]」より)

(中島 省吾=メディアプラネット)



 企業内で使用することを目的に作られたWindows NT系のOSは,「セキュリティ機能がある」といわれる。例えば,顧客情報を管理する部署では,多くの企業や個人の情報を扱っているため,誰もがこれらの情報にアクセスできるようでは困る。そこで特定の管理者や担当者だけに,データへのアクセス権を与えることになる。これがWindows NT以来のセキュリティ機能の根幹になっている。

 これらを実現しているのは,ユーザー・アカウントをネットワークにわたり管理するとともに,複数のプログラムが独立して稼働できる環境を用意し,共有リソースのアクセス権をアカウントに付与する——など,もろもろの技術の集積である。

 今回はこれらの技術のうち,アクセス権をどのように付与しているのか,それがどのようにアクセス制限につながっているのか,そのメカニズムについて解説しよう。

どんなリソースにもアクセス権を設定できる


△ 図をクリックすると拡大されます
図1●フォルダもプリンタも,同じ仕組みでアクセスを設定できるのはなぜだろう?

△ 図をクリックすると拡大されます
図2●オブジェクト指向のカプセル化
 Windows XPでは,フォルダやファイルに対してアクセス権を設定できる一方で,プリンタやモデムに対してもアクセス権を設定できる(図1)。実際にフォルダでもプリンタでも,それぞれアイコンからプロパティ画面を開き,[セキュリティ]タブに切り替えると,そのフォルダやプリンタのアクセス権を同じ形式で確認できる。

 これらは物理的に全く違う構造であるにもかかわらず,なぜWindows XPは,同じようにアクセス権を設定したり,確認したりできるのだろうか。また,Windows XPは,それらにアクセスできるユーザーかどうかを,何によって判断しているのだろうか。

 Windows XPでは,ファイルやプリンタは「オブジェクト」という単位でとらえられている。これをコンピュータの世界では「オブジェクト指向」と呼んでいる。オブジェクト指向で考えるのは,ファイルやプリンタといったリソースだけでない。

 プログラムは「プロセス」という単位で動いており,プロセスはさらに「スレッド」という単位に分解できる。Windows XPでは,複数のスレッドを同時に実行している。ここで言いたいことは,プロセスもスレッドも,OSのコアになるプログラムにとっては,オブジェクトでしかないということだ。

 オブジェクト指向の特徴は,本来バラバラに存在している「データ」と「操作」を,オブジェクトという単位でまとめるところにある。そして,データへのアクセスは,公開された「操作」でしかできないようになっている。これを「カプセル化」と呼ぶ(図2)。Windows XPにおいてすべてをオブジェクトとしてとらえているのは,カーネル・モードのプログラムから見た視点である。ユーザー・モードのプログラムは,あくまで決められた操作に従っているに過ぎない。

独立性を高めるオブジェクト指向
 Windows XPが,なぜオブジェクト指向を採用するのかと言えば,Windowsのプログラム部品である各コンポーネントや,それらが扱うデータなどの独立性が高まるからである。

 例えば,カーネル・モードには,プロセスを管理する「プロセス・マネージャ」や,ディスクなどのデバイス・ドライバを管理する「I/Oマネージャ」が動作している。これらWindowsのコンポーネントは,プロセスやファイルを直接操作するのではなく,それらをオブジェクトとして扱う。オブジェクトへのアクセスは,何通りかある所定の操作方法を採るため,コンポーネントがデータを直接操作できない。つまり,コンポーネントとデータが完全に分離されているので,オブジェクトがどんなデータを含んでいようと,コンポーネントにとっては同じ扱いとなる。これがオブジェクト指向を採用する最大の利点だ。

 ところが「プロセス」や「ファイル」といったリソースを,すべて統一されたオブジェクトという形に仕立てるには,集中的にオブジェクトを管理するマネージャが必要となる。それが「オブジェクト・マネージャ」である。

 例えば,プロセス・マネージャは,プロセスをオブジェクトにするため,オブジェクト・マネージャに対してプロセス・オブジェクトの生成を依頼する。依頼を受けたオブジェクト・マネージャは,プロセス・マネージャに対して,プロセスそのものを渡すのではなく,プロセス・オブジェクトのハンドルを渡す。

 「ハンドル」というのは,オブジェクトに与えられる一意の識別番号だと思ってもらえればいい。つまり,オブジェクトの管理はあくまでもオブジェクト・マネージャが行い,オブジェクトを扱いたい場合は,そのハンドルを利用するのである。他のコンポーネントもそのプロセスを利用したいときは,オブジェクト・マネージャからハンドルをもらう。ハンドルさえあれば,そのプロセス・オブジェクトを扱えるからだ。

セキュリティ参照モニターがアクセスを監視


△ 図をクリックすると拡大されます
図3●セキュリティ参照モニターの役割
 さらに,重要なことを付け加えておこう。Windowsのあるコンポーネント(オブジェクト)が,別のオブジェクトを利用するときには,カーネル・モードにあるプログラムが利用していいかどうかのチェックを行っているのである。これがアクセス権のチェックである。

 アクセス権のチェックは,次のような仕組みで行われる(図3)。

 例えば,「オブジェクトA」が「オブジェクトB」にアクセスしようとする状況を考える。

 まず,オブジェクトAはオブジェクト・マネージャに対して,オブジェクトBのハンドルを要求する。要求を受けたオブジェクト・マネージャは,ハンドルを渡していいかどうかを,「セキュリティ参照モニター(Security Reference Monitor)」というカーネル・モードで動いているコンポーネントに調べてもらう。

 セキュリティ参照モニターは,何を基にそれを判断するか——その情報とは,「アクセス・トークン」と「セキュリティ記述子」と呼ばれるものである。アクセスする側のオブジェクトAは「アクセス・トークン」を持っており,アクセスされる側のオブジェクトBには「セキュリティ記述子」が備わっている。

 そして,セキュリティ参照モニターがアクセス・トークンとセキュリティ記述子を突き合わせて,アクセスの可否を判断し,結果をオブジェクト・マネージャに知らせる。オブジェクト・マネージャはその判断に基づいて,ハンドルを渡したり,渡さなかったりしている。

 アクセス可能でハンドルが渡されたら,オブジェクトAはオブジェクトBにアクセスできる。

ログオン時に生成されるアクセス・トークン


△ 図をクリックすると拡大されます
図4●アクセス・トークンの中にある情報
 ここで登場した「アクセス・トークン」と「セキュリティ記述子」について,もう少し詳しく中身を見ていこう。

 アクセス・トークンは,ユーザーがログオンして認証が成功すると作成されるオブジェクトである。アクセス・トークンには,様々な情報が含まれている。特に重要なのは,ユーザーのSID,ユーザーが所属するグループのSID,デフォルトの随意ACLである(図4)。

 「SID(セキュリティID)」とは,コンピュータやユーザーに対して割り当てられる一意の値である。例外的に,アクセス・トークンに含まれているユーザーのSIDは,現在ログオン中のセッションを識別するためにあり,他のSIDとは異なってログオンごとに変化する。「ログオン・セッションSID」とも呼んでいる。