Trusted Solaris 7 は、CMW ラベル、機密ラベルの 2 種類のラベルを使用します。情報ラベル (IL) は Trusted Solaris 7 およびそれ以降のバージョンではサポートしません。Trusted Solaris ソフトウェアは、ADMIN_LOW として稼動している既存リリースのシステムから、通信とファイル上の情報ラベルを再度インタプリタ処理します。ただし、CMW ラベルは、機密ラベルと情報ラベルを 1 つの単位として扱うための構成体にすぎません。すべてのプロセスとオブジェクトには、CMW ラベルがありますが、情報ラベル部は ADMIN_LOW に限定されます。
CMW ラベルの機密ラベル部は、プロセスとオブジェクト内のデータの格付けに対するアクセスの制御と管理をする必須アクセス制御 (MAC) 機構です。CMW ラベルの機密ラベル部は、情報がどのレベルで保護される必要があるかについても示します。プロセスがオブジェクトにアクセスする場合は常に、第 1 章「API とセキュリティポリシーの紹介」に説明されているように、必須アクセスチェックと任意アクセスチェックが実行されます。
情報ラベルがサポートされなくなったことにより、Trusted Solaris 7 では次のような影響が生じます。
ウィンドウラベルに情報ラベルは表示されません。機密ラベルだけが括弧内に表示されます。
オブジェクトに対して情報ラベルを設定しても何の効果もありません。
オブジェクトの情報ラベルを取得すると、常に ADMIN_LOW が返されます。
特定のユーティリティ、ライブラリ関数、およびシステムコールは情報ラベルを操作することができますが、その結果の文字列をオブジェクトに対して設定することはできません。
この章では、ラベルの初期化、CMW ラベルのラベル部の取得、ラベルの比較など、一般的なラベル操作を実行するプログラミングインタフェースについて説明します。また、プロセスやファイルシステムオブジェクトの CMW ラベルにアクセスするプログラミングインタフェースについても説明します。この章で説明するプログラミングインタフェースのコード例は、第 6 章「ラベルのコード例」で示します。
認可上限は機密ラベルと同じ構成をしていますが、実行する機能は異なります。この類似性のため、この章のインタフェースの中には認可上限をパラメータとして使用できるものもあります。また、一部のインタフェースは認可上限を処理するインタフェースを含みます。しかし、認可上限は異なる機能を持つため、認可上限を管理するインタフェースはすべて、認可上限を使用するコード例と共に、第 7 章「プロセス認可上限」で説明しています。
CMW ラベルは、すべてのプロセスとオブジェクトのラベル付けを行う構成体です。CMW ラベルとは、機密ラベルと情報ラベルがプログラム上で 1 つの単位として処理されたり、あるいは個々にアクセスされるように、2 つのラベルを結合したものです。
機密ラベルには、1 つの ID フィールド、 1 つの階層的な格付け、1 つ以上の非階層的なコンパートメントが 1 セット含まれます。格付けは、階層内でのレベルを表します。一方、コンパートメントは、システム内の情報の範囲区分を表します。コンパートメントは、特定の範囲の情報を知る必要のある人物だけにアクセスを託すためのものです。たとえば、Secret 格付けの人物は、コンパートメントリストに指定された機密情報に対するアクセス権がありますが、それ以外の機密情報に対するアクセス権はありません。機密ラベルの格付けとコンパートメントの両方によってプロセスまたはオブジェクトの機密レベルが決定されます。
機密ラベルの比較とは、プロセス CMW ラベルの機密ラベル部を、対象となる CMW ラベルの機密ラベル部と比較することです。プロセスに対するアクセス権は、プロセスの機密レベルが対象となる CMW の機密レベルより優位かどうかに基づいて、付与または拒否されます。同等と優位の関係は、「ラベルの関係の確認」で説明しています。
CMW ラベルは、Trusted Solaris 7 のユーザーインタフェースで、単一の機密ラベルを表します。
ラベルは、ワークスペースとほかのプロセスから取得されます。ユーザーは、現在作業中のワークスペースの機密ラベルにおいてのみ、プロセスを開始することができます。
プロセスがワークスペースから開始されると、プロセスの CMW ラベルはワークスペースの CMW ラベルの機密ラベルの値を継承します。
fork(2) により新しいプロセスが作成されると、新しいプロセスはその呼び出しプロセスの CMW ラベル値を継承します。
新しいプログラムが exec(1) により開始されるとき、exec を実行するプロセスは、新しいプログラムのファイルに対する任意アクセス権と必須アクセス権の両方を必要とします。
setcmwplabel(2) システムコールは、プログラム中からプロセスの CMW ラベルを設定します。このシステムコールは、新しいプロセスを fork または exec により起動したあとで、そのプロセスを呼び出し元のプロセスとは別の CMW ラベルで動作させたいときに使用してください。このとき、特権が必要になる場合があります。詳細は、「特権の必要な操作」を参照してください。
プロセスによってオブジェクトが作成されると、オブジェクトはその呼び出し元プロセスの CMW ラベル値を継承します。ラベル表示の設定に応じて、ADMIN_LOW ラベルまたはシステム上で次にもっとも低いラベルがユーザーに表示されます。ラベル表示とは、「プロセスのセキュリティ属性フラグの取得と設定」で説明されている、プロセスのセキュリティ属性フラグです。
特権プロセスがオブジェクトに対し下位書き込みを行うと、システムはオブジェクトの機密ラベルを、プロセスの機密ラベルと同じになるよう変更します。この変更により、より高い機密ラベルでプロセスから書き込まれる情報が、より低い機密ラベルで動作しているほかのプロセスによってアクセスされないように保護します。
setcmwlabel(2) システムコールは、ファイルシステムオブジェクトの CMW ラベルをプログラム中から設定します。
承認を受けたユーザーは、ファイルマネージャを使用して、既存のファイルの CMW ラベルの機密ラベルを変更できます。
プロセスやファイルシステムオブジェクトの CMW ラベルの取得と設定を行うシステムコールは、プロセスやファイルシステムオブジェクトに対する必須アクセス権と任意アクセス権を必要とします。また、アクセスがシステムセキュリティポリシーにより拒否される場合は、特権が必要になります。システムコールの一覧は、「システムコール」を参照してください。
呼び出し元のプロセスは、バイナリと ASCII 間でラベルを変換するときに、プロセスの機密ラベルが変換されるラベルより優位でないときは、有効セット内に sys_trans_label 特権を必要とします。この特権は、プロセスの機密ラベルが検査されるラベルより優位でない場合に、ラベルが有効であるかどうかを検査する場合にも必要になります。
呼び出し元プロセス自体の機密ラベルを現在とは異なるラベルに変更したいとき、呼び出しプロセスの有効セット内に proc_setsl 特権が必要となります。
呼び出し元プロセス自体が所有していないファイルの機密ラベルを降格する場合、呼び出し元プロセスの有効セット内に file_owner 特権が必要となります。
プロセスは、その有効セット内の file_downgrade_sl 特権を使用して、ファイルシステムオブジェクトの機密ラベルを、オブジェクトの現在の機密ラベルよりも優位でない機密ラベルに設定できます。
プロセスは、その有効セット内の file_upgrade_sl 特権を使用して、ファイルシステムオブジェクトの機密ラベルを、オブジェクトの現在の機密ラベルより優位な機密ラベルに設定できます。
この節では、アクセス制御の回避や、機密ラベルの変更を行うために、プログラムが、特権を必要とする場合に守るべきガイドラインを示します。
ほとんどのアプリケーションは、次のどれかの方法で動作するため、アクセス制御を回避するときに特権は使用しません。
1 人または複数のユーザーによって 1 つの機密ラベルで起動され、オブジェクト内のデータにその同じ機密ラベルでアクセスする
1 人または複数のユーザーによって 1 つの機密ラベルで起動され、オブジェクト内のデータに別の機密ラベルでアクセスする。しかし、「セキュリティポリシー」で説明されているように、必須アクセスの操作がシステムセキュリティポリシーにより許容される
1 人または複数のユーザーによって複数の異なる機密ラベルで起動され、オブジェクト内のデータにマルチレベルディレクトリを介して同じ機密ラベルでアクセスする。マルチレベルディレクトリについては第 8 章「マルチレベルディレクトリ」で説明しています。
アプリケーションがそのプロセスの機密ラベルとは異なる機密ラベルでデータにアクセスし、そのアクセスが拒否される場合、プロセスは特権を必要とします。特権によりアプリケーションは、file_mac_read、file_dac_read、 file_mac_write、file_dac_write、file_mac_search、または file_dac_search を使用して必須または任意のアクセス制御の適用を回避したり、proc_setsl を使用して必須アクセスが与えられるようにプロセスの機密ラベルを変更したり、あるいは file_upgrade_sl、file_downgrade_sl を使用してデータの機密ラベルを昇格または降格することができます。どのような方法でアクセスするにせよ、アクセスされるデータの格付けに害を及ぼすことがないように、この節に示されたガイドラインを守ってアプリケーションを設計する必要があります。
特権を使用して必須アクセス制限が適用されないようにする場合、アプリケーションは、データを読み取るレベルよりも低い機密ラベルでデータを書き込むことができません。また、プログラムエラーによるデータの降格を行うことがないようにアプリケーションを設計してください。
アプリケーションがそれ自体の機密ラベルまたは別のオブジェクトの機密ラベルを変更する場合、次のガイドラインに従ってください。
可能なかぎり、機密ラベルを昇格する
機密ラベルを昇格するプログラムは、機密ラベルを降格するプログラムよりも安全です。これは、アプリケーションエラーが情報漏れを引き起こしたとしても、データは降格されるのではなく昇格されるためです。データの昇格はデータ格付けを必要以上に高いものにしますが、セキュリティは守られます。特権を使用して機密ラベルを降格することもできますが、これらの特権は十分な注意を払って使用してください。
プロセスの機密ラベルの変更は必ず一度に留める。プロセスの機密ラベルの変更を行うと、データが異なるレベル間で誤って転送される危険性が高まります。プロセスの機密ラベルに対するあらゆる変更は、プロセスのアドレス空間の情報を昇格または降格します。
ファイルやプロセスの機密ラベルを変更する場合、機密データがほかのプロセスに使用されないように、ファイル記述子をすべてクローズする
プロセスの機密ラベルを変更する代わりに、新しいプロセスを fork() により起動し、フォークされた子プロセスの機密ラベルを変更することによって、子プロセスが、親プロセスのデータとは異なるレベルで作業できるようになります。子プロセスは、親プロセスに対して情報を返すか、あるいは別のプロセスに情報を送る必要があります。
変更された機密レベルで子プロセスが返す情報には、必要不可欠な情報だけが含まれるようにします。たとえば、処理が成功したか失敗したかを表示しても、実際のデータは表示しないようにします。特定の情報を渡すことにより、処理に使用されるデータを守り、1 つのレベルのデータが別のレベルのデータと混ざることのないようにします。
この章で説明しているプログラミングインタフェースを使用するには、次のヘッダーファイルが必要です。
#include <tsol/label.h>
この章の例は、次のライブラリを使用してコンパイルしています。
-ltsol
データ構造体 bclabel_t は、バイナリの CMW ラベルを示します。インタフェースでは、bclabel_t 型構造のバイナリ CMW ラベルを使用します。
CMW ラベルフラグの値を定義する setting_flag 型の定義を次に示します。
SETCL_SL - CMW ラベルの機密ラベル部を設定する。
SETCL_ALL - CMW ラベル全体を設定する。
bslabel_t 型の定義は、バイナリ CMW ラベルの機密ラベル部を示します。インタフェースでは、バイナリの機密ラベルは、bslabel_t 型の変数のパラメータとして受け渡されます。bslabel_t 型の定義は、blevel_t 構造と互換性があります。
blevel_t 構造は、機密ラベル、情報ラベル、または認可上限の、格付けとコンパートメントセットのバイナリレベルを示します。インタフェースでは、blevel_t 型構造体のバイナリレベルが受け渡されます。
bclear_t 型または bslabel_t 型の変数は、blevel_t 型のパラメータを受け入れる関数に渡すことができます。
brange_t データ構造体は、機密ラベルの範囲を示します。この構造は、最下位ラベルと最上位ラベルを保持します。構造フィールドは、variable.lower_bound と variable.upper_bound として参照されます。
set_id データ構造体は、現在、次の整数値を受け入れます。1 = SYSTEM_ACCREDITATION_RANGE (システム認可範囲); 2 = USER_ACCREDITATION_RANGE (ユーザー認可範囲)。
label_info 構造には、label_encodings ファイル内の項目の長さが指定されます。この構造は、labelinfo(3) によって返されます。
フィールド |
内容 |
slabel_len |
機密ラベルの最大長 |
clabel_len |
CMW ラベルの最大長 |
clear_len |
認可上限ラベルの最大長 |
vers_len |
バージョン文字列の長さ |
header_len |
プリンタバナーの最大長 |
protect_as_len |
bcltobanner(3) が返すプリンタバナーページの、ヘッダー文字列の最大長 |
caveats_len |
bcltobanner(3) が返すプリンタバナーページの、文字列の最大長 |
channels_len |
プリンタバナーページのチャネル文字列の最大長 |
banner_field 構造には、ASCII コードに変換されたラベルと文字列が含まれます。このラベルと文字列は、プリンタバナー、トレーラページ、および文書の本文ページの先頭と最後に表示されます。この構造は、bcltobanner(3) によって返されます。最初の 5 つのフィールドは、文字列へのポインタです。次の 5 つのフィールドは、対応する文字列ポインタの指す領域に対して事前に割り当てられたメモリーの長さを示すショート整数 (short integer) です。
フィールド |
内容 |
header |
バナーページとトレーラページの先頭と最後に表示される文字列 |
protect_as |
バナーページの protect as セクションに表示される文字列 |
caveats |
バナーページの caveats セクションに表示される文字列 |
channels |
handling channels セクションに表示される文字列 |
header_len |
ヘッダーの文字列に事前に割り当てられたメモリーの長さ |
protect_as_len |
protect as セクションの文字列に事前に割り当てられたメモリーの長さ |
ilabel_len |
情報ラベルの文字列に事前に割り当てられたメモリーの長さ |
caveats_len |
caveats セクションの文字列に事前に割り当てられたメモリーの長さ |
channels_len |
channels セクションの文字列に事前に割り当てられたメモリーの長さ |
プロセスとファイルシステムオブジェクトのラベルについて、一般的な操作を行なったりアクセスしたりするときに、次に示すプログラミングインタフェースを使用できます。
次のシステムコールは、ファイルまたはプロセスの CMW ラベルの取得と設定を行なったり、ファイルシステムのラベル範囲を取得したりします。
別のプロセスまたはファイルシステムのオブジェクトにラベルを設定するプロセスはすべて、label_encodings ファイルの定義どおりに有効なラベルを設定しなければなりません。また、この種のプロセスは、正しいバイナリ型のラベルを渡す必要があります。ASCII からバイナリへの変換機能は、変換により正しいバイナリラベルが得られるように、できるかぎりラベルを修正します。しかし、ラベルが有効であるか、bslvalid(3) ルーチンを使用してさらに調べる場合もあります。正しく構築されたバイナリラベルでも、一定のシステムまたはユーザーには無効な場合もあるため、ラベルがシステム認可またはユーザー認可の範囲内であるか、blinset(3) ルーチンを使用して検査してください。
次のシステムコールは、パス名またはファイル記述子を使用して、ファイルの CMW ラベルの取得と設定を行います。詳細は、setcmwlabel(2) と getcmwlabel(2) のマニュアルページを参照してください。
int setcmwlabel( const char *path, const bclabel_t *label, const setting_flag_t flag); int getcmwlabel( const char *path, const bclabel_t *label); int fsetcmwlabel( const int fd, const bclabel_t *label, const setting_flag_t flag); int fgetcmwlabel( const int fd, bclabel_t *label); int lsetcmwlabel( const int fd, const bclabel_t *label, const setting_flag_t flag); int lgetcmwlabel( const int fd, bclabel_t *label);
次のシステムコールは、プロセスの CMW ラベルの取得と設定を行います。詳細は、setcmwplabel(2) と getcmwplabel(2) のマニュアルページを参照してください。
int setcmwplabel( const bclabel_t *label, const setting_flag_t flag); int getcmwplabel( const bclabel_t *label);
次のシステムコールは、ファイルシステムのラベル範囲を取得します。詳細は、getcmwfsrange(2) のマニュアルページを参照してください。
int getcmwfsrange( char *path, brange_t *range); int fgetcmwfsrange( int fd, brange_t *range);
次のライブラリルーチンは、ラベルのアクセス、初期化、比較、変換、および検証を行います。また、label_encodings(4) 情報の取得も行います。
次のルーチンは、CMW ラベルを ADMIN_HIGH、ADMIN_LOW、または NULL に似た定義されていない状態に初期化します。詳細は、blmanifest(3) のマニュアルページを参照してください。
void bclhigh( bclabel_t *label); void bcllow( bclabel_t *label); void bclundef( bclabel_t *label);
次のルーチンは、CMW ラベルの機密ラベル部にアクセスします。詳細は、blportion(3) のマニュアルページを参照してください。
void getcsl( bslabel_t *destination_label, const bclabel_t *source_label); void setcsl( bclabel_t *destination_label, const bslabel_t *source_label); bslabel_t *bcltosl( bclabel_t *label);
次のルーチンは、機密ラベルを ADMIN_HIGH、ADMIN_LOW、定義されていない状態のいずれかに初期化します。詳細は、blmanifest(3) のマニュアルページを参照してください。
void bslhigh( bslabel_t *label); void bsllow( bslabel_t *label); void bslundef( bslabel_t *label);
次のルーチンは、 level1 と level2 の 2 つのレベルを比較し、両者が同等か、level1 が level2 よりも優位であるか、あるいは level1 が level2 よりも完全に優位であるかを調べます。レベルとは、機密ラベルまたは認可上限内の、格付けおよびコンパートメントのことです。
返される値のうち、0 以外の値は true で、0 は false です。詳細は、 blcompare(3) のマニュアルページを参照してください。
int blequal( const blevel_t *level1, const blevel_t *level2); int bldominates( const blevel_t *level1, const blevel_t *level2); int blstrictdom( const blevel_t *level1, const blevel_t *level2); int blinrange( const blevel_t *level, const brange_t *range);
次のルーチンは、ラベルのタイプを検査し、設定します。ラベルには、定義済みか末定義の CMW ラベル、機密ラベル、情報ラベルがあります。詳細は、bltype(3) のマニュアルページを参照してください
int bltype( const void *label const unsigned char type); void setbltype( void *label const unsigned char type);
次のルーチンは、 2 つのレベルを比較し、それら 2 つのレベルの範囲内の、高い方の下限 (blminimum(3)) または低い方の上限 (blmaximum(3)) を示す機密レベルを見つけます。レベルとは、機密ラベルまたは認可上限内の、格付けとコンパートメントのことです(詳細は、blcompare(3) のマニュアルページを参照)。
void blmaximum( blevel_t *maximum_label const blevel_t *bounding_label); void blminimum( blevel_t *minimum_label const blevel_t *bounding_label);
label_encodings ファイルは、システム管理者によって管理される ASCII ファイルで、サイト固有のラベルの定義と制約が記載されています。このファイルは、/etc/security/tsol/label_encodings に保存されます。label_encodings ファイルの詳細は、『Trusted Solaris のラベル管理』と『コンパートメントモードワークステーションのラベル作成: エンコード形式』を参照してください。
次のルーチンは、先頭から順に、最大文字列長の情報、使用中の label_encodings ファイルのバージョン、指定されたバイナリレベルに対する ASCII カラー名などの label_encodings ファイルで指定されている情報を戻します。
最大文字列長。labelinfo(3) のマニュアルページを参照してください。
int labelinfo( struct label_info *info);
使用中のバージョン。詳細は、labelvers(3) のマニュアルページを参照してください。
int labelvers( char **version, const int length);
バイナリレベルに対する ASCII カラー名。詳細は、bltocolor(3) のマニュアルページを参照してください
char bltocolor( const blevel_t *label); char bltocolor_t( const blevel_t *label, const int size, char * color_name);
次のルーチンは、指定された機密ラベルがシステムで有効であるか、つまり、システムの label_encodings ファイルで定義されているかを検査します。詳細は、blvalid(3) のマニュアルページを参照してください。
int bslvalid( const bslabel_t *senslabel);
次のルーチンは、機密ラベルが、システムの label_encodings ファイルで設定されているとおりのシステム認可範囲にあるかを検査します。詳細は、blinset(3) のマニュアルページを参照してください。
int blinset( const blevel_t *senslabel, const set_id *id);
次のルーチンは、バイナリの CMW ラベルまたは機密ラベルを ASCII に変換し、再び元に戻します。文字列からバイナリに変換する場合、flag (フラグ) が NEW_LABEL か NO_CORRECTION に設定されていれば、文字列は ASCII でも 16 進でも構いません。詳細は、bltos(3) と stobl(3) のマニュアルページを参照してください。
バイナリラベルを ASCII へ変換する、指定された幅に応じて最終的なラベルの長さを変える、Motif ベースのグラフィカルユーザーインタフェース (GUI) で表示用のフォントリストを使用する、などの処理を行う各インタフェースの詳細は、第 15 章「トラステッド X ウィンドウシステム」を参照してください。
int bcltos( const bclabel_t *label, char **string, const int length, const int flags); int stobcl( const char *string, bclabel_t *label, const int flags, int *error); /* 文字列を変換し、長さを変える */ char *sbcltos( const bclabel_t *label, const int length); /* プリンタバナーとヘッダーページに含めるために変換する */ char *bcltobanner( const bclabel_t *label, struct banner_fields *fields, const int flags);
int bsltos( const bslabel_t *label, char **string, const int length, const int flags); int stobsl( const char *string, bslabel_t *label, const int flags, int *error); /* 文字列を変換し、長さを変える */ char *sbsltos( const bslabel_t *label, const int length);
次のルーチンは、バイナリの CMW ラベル、機密ラベルを 16 進に変換し、再び元に戻します。btohex(3) と hextob(3) のマニュアルページを参照してください。
char h_alloc( const unsigned char id); void h_free( char *hex);
char *bcltoh( const bclabel_t *label); char *bcltoh_r( const bclabel_t *label, char *hex); int htobcl( const char *hex, bclabel_t *label);
char *bsltoh( const bslabel_t *label); char *bsltoh_r( const bslabel_t *label, char *hex); int htobsl( const char *hex, bslabel_t *label);