Trusted Solaris 開発ガイド

第 7 章 プロセス認可上限

アプリケーションがワークスペースから起動されると、ユーザーのセッション認可上限がそのプロセスに設定されます。この認可上限をプロセス認可上限と言います。このアプリケーションが fork によりプロセスを生成するときか、新しいプロセスの認可上限は、呼び出し元プロセスの認可上限と同じものに設定されます。また、アプリケーションがプログラムを exec により実行するときも、新しいプログラムの認可上限は呼び出し元プロセスの認可上限と同じものに設定されます。

セッション認可上限は、ログイン時に選択されます。セッション認可上限は、ユーザーがそのログインセッションで作業できる上限として、ユーザー認可上限よりも劣位でもっとも低い上限を設定します。ユーザー認可上限は、システム管理者がユーザーの実行プロファイルに対し割り当てるもので、ユーザーがあらゆるログインセッションで作業を行うことのできる、もっとも高い機密ラベルを決定します。

ユーザーがワークスペースからアプリケーションを起動する場合、プロセスの CMW ラベルには、ワークスペースの CMW ラベル内の値が設定されます。プロセスはユーザーのセッション認可上限とワークスペースの CMW ラベルを取得するため、プロセス認可上限は、常にプロセスの CMW ラベルの機密ラベル部よりも優位であるか同等です。この規則を変更する特権は存在しません。

認可上限には、CMW ラベルの機密ラベル部と同様に、1 つの格付けと 1 つ以上のコンパートメントのセットが含まれます。認可上限は機密ラベルではありませんが、次に示す方法で、プロセスの機密ラベルと併用して使用されます。

この章では、プロセス認可上限の取得と管理を行うプログラミングインタフェースについて説明します。tsoluser データベース内のユーザーの認可上限情報を読み取るインタフェースの詳細は、第 10 章「ユーザーとプロファイルのデータベースエントリへのアクセス」を参照してください。

特権を必要とする処理

プロセスは、それ自身のプロセス認可上限をユーザーのセッション認可上限または親プロセスの認可上限と同等でないように変更する場合、有効セット内に proc_setclr 特権を必要とします。この特権はまた、ある認可上限が有効かどうか label_encodings(4) ファイルの設定を検査するときに、プロセスの機密ラベルが検査されるラベルより優位でない場合は、この特権が必要になります。

バイナリ認可上限を ASCII に変換する場合、プロセスの機密ラベルが変換される認可上限より優位でないと、プロセスの有効セット内に sys_trans_label 特権が必要になります。この特権は、プロセスの機密ラベルが認可上限よりも優位でない場合に、認可上限が有効であるかを検査するときにも必要です。

データ型、ヘッダーファイル、ライブラリ

この章で説明しているプログラミングインタフェースを使用するには、次のヘッダーファイルが必要です。

#include <tsol/label.h>

この章の例は、次のライブラリを使用してコンパイルしています。

-ltsol

プロセス認可上限

インタフェースは、bclear_t 型の変数で、バイナリのプロセス認可上限をパラメータとして受け取り、返します。

バイナリレベル

レベルとは、機密ラベル、認可上限のいずれかの格付けとコンパートメントセットのことです。インタフェースでは、バイナリのレベルが blevel_t 型の構造で、パラメータとして受け取り、返します。

型の互換性

bclear_t 型または bslabel_t 型の変数は、blevel_t 型のパラメータを受け取れる関数に渡すことができます。

プログラミングインタフェース宣言

次に、プロセス認可上限を管理するプログラミングインタフェースを示します。

システムコール

次のシステムコールは、呼び出しプロセスの認可上限の取得と設定を行います。詳細は、getclearance(2)setclearance(2) のマニュアルページを参照してください。


警告 - 警告 -

認可上限を設定するプロセスはすべて、有効な認可上限を label_encodings(4) ファイルに指定されているように設定し、正しいバイナリ形式の認可上限を渡す必要があります。ASCII からバイナリへの変換を行うと、変換から正しいバイナリ認可上限が生成されるように、可能なかぎりの修正が認可上限に加えられます。しかし、blvalid(3) ルーチンを使用して、その認可上限が有効か検査した方がよい場合もあります。


int		getclearance(				bclear_t *clearance);
 int		setclearance(				bclear_t *clearance);

ライブラリルーチン

プロセス認可上限の初期化、比較、変換、および検証に、ライブラリルーチンを使用できます。

初期化

次のルーチンは、認可上限を ADMIN_HIGHADMIN_LOW、または NULL に似た未定義の状態に初期化します。詳細は、blmanifest(3) のマニュアルページを参照してください。

void		bclearhigh(				bclear_t *clearance);
 void		bclearlow(				bclear_t *clearance);
 void		bclearundef(				bclear_t *clearance);

比較

次のルーチンは、2 つのレベルを比較し、両者が同等か、level1level2 よりも優位であるか、あるいは level1 が level2 よりも完全に優位であるかを確認します。レベルとは、機密ラベル、情報ラベル、認可上限のいずれかの、格付けとコンパートメントセットのことです。biltolev(3) ルーチンを使用して情報ラベル (格付け、コンパートメント、マーキング) をレベル (格付けとコンパートメントのみ) に変換するか、あるいは次の 2 つの節のルーチンを使用して、2 つの情報ラベルや 2 つのマーキングセットを比較してください。

返される値のうち、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);

認可上限の型

bltype(3) ルーチンは、認可上限の型を検査します。setbltype(3) ルーチンは、認可上限の型を設定します。認可上限は、定義してもしなくてもかまいません。詳細は、bltype(3) のマニュアルページを参照してください。

int		bltype(				const void *clearance,
 						const unsigned char type);
 void		setbltype(				void *clearance,
 						const unsigned char type);

レベルの上下限

次のルーチンは、2 つのレベルを比較します。2 つのレベルで定められた範囲内で、blminimum(3) によりもっとも高い下限の機密レベルを見つけ、blmaximum(3) によりもっとも低い上限の機密レベルを見つけます。レベルとは、機密ラベル、情報ラベル、認可上限のいずれかの、格付けとコンパートメントセットのことです。情報ラベルをレベルに変換するには、biltolev(3) ルーチンを使用します。詳細は、blminmax(3) のマニュアルページを参照してください。

void		blmaximum(				blevel_t *maximum_label,
 						const blevel_t *bounding_label);
 void		blminimum(				blevel_t *minimum_label,
 						const blevel_t *bounding_label);

有効な認可上限

次のルーチンは、指定された認可上限がシステムで有効であるかを確認します。詳細は、blvalid(3) のマニュアルページを参照してください。

int		bclearvalid(				const bclear_t *clearance);

バイナリと ASCII 間の変換

次のルーチンは、認可上限をバイナリから ASCII に変換し、再び元に戻します。詳細は、stobl(3) のマニュアルページを参照してください。


注 -

バイナリラベルを ASCII に変換したり、Motif ベースのグラフィカルユーザーインタフェース (GUI) で表示するために、目的のラベルを指定された幅とフォントリストに従ってクリッピングするインタフェースの詳細は、第 15 章「トラステッド X ウィンドウシステム」を参照してください。


int		bcleartos(				const bclear_t *clearance,
 						char **string,
 						const int len,
 						const int flags);

 int		stobclear(				const char *string,
 						bclear_t *clearance,
 						const int flags, int *error);

 char*		sbcleartos(				const bclear_t *clearance,
 						const int len);

バイナリと 16 進間の変換

次のルーチンは、認可上限をバイナリから 16 進に変換し、再び元に戻します。詳細は、btohex(3) のマニュアルページを参照してください。

char		*h_alloc(				const unsigned char id);
 void		h_free(				char *hex);

 char		*bcleartoh_r(				const bclear_t *clearance,
 						char *hex);
 char		*bcleartoh(				const bclear_t *clearance);
 int		htobclear(				const char *s,
 						bclear_t *clearance);

プロセス認可上限の処理

プログラムは、そのプロセス認可上限を取得しないと、認可上限に対する処理を実行できません。次の短いプログラムは、呼び出しプロセスのプロセス認可上限を取得します。

#include <tsol/label.h>

 main()
 {
 	int			retval;
 	bclear_t			pclear;

 	retval = getclearance(&pclear);
 	printf("Retval = %d¥n", retval);
 }

printf 文によって、次のように出力されます。

Retval = 0

プロセス認可上限の設定

このプロセスは、プロセス認可上限を別の値に設定する場合、その新しい値がプロセス自身の CMW ラベルの機密ラベル部と同等でないときには、proc_setclr 特権を必要とします。新しいプロセス認可上限は、 setclearance(2) システムコールを使用して設定します。次の例は、認可上限の構造を ADMIN_HIGH に初期化し、それを setclearance(2) システムコールに渡します。

#include <tsol/label.h>

 main()
 {
 	int			retval;
 	bclear_t			hiclear, undef, loclear;

 	bclearhigh(&hiclear);

/* 有効セット内で proc_setclr をオン (有効) にする */
 	retval = setclearance(&hiclear);
/* proc_setclr 特権をオフ (無効) にする */

 	printf("Retval = %d¥n", retval);
 }

printf(1) 文によって、次のように出力されます。

Retval = 0

認可上限構造の初期化

認可上限は、ADMIN_LOW または ADMIN_HIGH に初期化したり、その型を検査したりできます。次の例は、undefNULL に似た未定義の状態に初期化し、loclearADMIN_LOW に初期化しています。その後、loclear の型を検査し、その型を未定義に設定し、再び検査します。認可上限は、ID フィールドが SUN_CLR_UN に初期化される場合、未定義の状態です。未定義の認可上限は無効です。認可上限は、ラベル構造内の ID フィールドが SUN_CLR_ID に初期化されるときに定義されます。

#include <tsol/label.h>

 main()
 {
 	int			retval;
 	bclear_t			loclear, undef;

 	bclearlow(&loclear);
 	bclearundef(&undef);

 	retval = bltype(&loclear, SUN_CLR_ID);
 	printf("Is clearance defined? %d¥n", retval);

 	setbltype(&loclear, SUN_CLR_UN);
 	retval = bltype(&loclear, SUN_CLR_ID);
 	printf("Is clearance defined? %d¥n", retval);
 }

printf(1) 文によって、次のように出力されます。0 以外は true で、0 は false です。

Is clearance defined? 1

Is clearance defined? 0

2 つのレベル間の関係の確認

レベルとは、機密ラベル、情報ラベル、認可上限のいずれかの格付けとコンパートメントセットのことで、データ型 blevel_t で定義されます。情報ラベルは、biltolev(3) ルーチンを使用してレベルに変換します。2 つのレベルには、同等、一方が他方より優位、一方が他方より完全に優位などの関係があります。

次の例は、プロセス認可上限をファイルの CMW ラベルの機密ラベル部と照らし合わせ、その関係 (同等、優位、完全な優位のいずれか) を確認します。プロセス認可上限は TOP SECRET A B、ファイルの CMW ラベルの機密ラベル部は Confidential であり、このプロセスは Confidential で動作しています。

#include <tsol/label.h>

 main()
 {
 	int			retval;
 	bclear_t			pclear;
 	bclabel_t			cmwlabel;
 	bslabel_t			senslabel;

 	retval = getclearance(&pclear);
 	retval = getcmwlabel("/export/home/zelda/afile", &cmwlabel);
 	getcsl(&senslabel, &cmwlabel);

 	retval = blequal(&pclear, &senslabel);
 	printf("Clearance equals sensitivity label? %d¥n", retval);

 	retval = bldominates(&pclear, &senslabel);
 	printf("Clearance dominates sensitivity label? %d¥n", retval);

 	retval = blstrictdom(&pclear, &senslabel);
 	printf("Clearance strictly dominates sensitivity label? %d¥n", retval);
 }

printf(1) 文によって、次のように出力されます。0 以外は true で、0 は false です。

Clearance equals sensitivity label? 0

Clearance dominates sensitivity label? 1

Clearance strictly dominates sensitivity label? 1

もっとも高いレベルともっとも低いレベルの検索

次の例は、blevel_t 型の 2 つの変数間の最大値と最小値を見つけます。このインタフェースでは、2 つのレベルが比較されます。2 つのレベルにより定められた範囲内で、blminimum(3) ルーチンにより、もっとも高い下限のレベルを、また、blmaximum(3) ルーチンによりもっとも低い上限のレベルを見つけることができます。レベルは、biltolev(3) ルーチンを使用してレベルに変換された、機密ラベル、認可上限、または情報ラベルのいずれかです。

次のコード例は、TS A B のプロセス認可上限と ADMIN_LOW の機密ラベルが作成する範囲から、もっとも高い下限ともっとも低い上限を見つけます。プロセスは、Confidential で動作しています。

この例の前半は、2 つのレベルのうち、より優位な格付けとすべてのコンパートメントでもっとも優位なコンパートメントを見つけ、その値を最初のパラメータに入れます。この処理は、ルーチンに渡される元のパラメータ値の両方よりも優位なレベルのうちでもっとも低いものを見つけるため、「もっとも低い上限の検索」と言います。

プロセスの機密ラベルがプロセス認可上限よりも優位でないため、プロセスは変換に sys_trans_label 特権を必要とします。第 3 章「特権」で説明している特権のブラケット化が必要な位置は、コード内のコメントで示してあります。

#include <tsol/label.h>

 main()
 {
 	int			retval, length = 0;
 	char			*string = (char *)0, *string1 = (char *)0;
 	bclear_t			clear;
 	bslabel_t			senslabel;

 	bsllow(&senslabel);
 	reval = getclearance(&clear);
 	blmaximum(&senslabel, &clear);

/* 有効セット内で sys_trans_label 特権をオン (有効) にする */
 	retval = bsltos(&senslabel, &string, length, LONG_WORDS);
/* sys_trans_label をオフ (無効) にする */

 	printf("Maximum = %s¥n", string);

printf(1) 文によって、次のように出力されます。TS ABLE BAKER は、TS A BADMIN_LOW より優位なもっとも低いレベルです。

Maximum = TS A B

例の後半は、格付けおよび、コンパートメントのうち、両方のパラメータに含まれているものの中でもっとも低い値を見つけ、その値を最初のパラメータに入れます。この処理は、渡される両方の元のパラメータ値より劣位であるもっとも高いレベルを見つけるため、「もっとも高い下限の検索」と言います。

	bsllow(&senslabel);
 	blminimum(&senslabel, &clear);
 	retval = bsltos(&senslabel, &string, length, LONG_WORDS);
 	printf("Minimum = %s¥n", string);
 }

printf(1) 文によって、次のように出力されます。ADMIN_LOW は、TS A BADMIN_LOW より劣位であり、もっとも高いレベルです。

Minimum = ADMIN_LOW

有効な認可上限

有効な認可上限とは、label_encodings(4) ファイルで定義されている認可上限を指します。認可上限が有効であるかを検査するには、bclearvalid(3) ルーチンを呼び出してください。TS A B で動作しているプロセスはこの認可上限と等しく、特権なしでこの処理を実行できます。

#include <tsol/label.h>
 main()
 {
 	int			retval, error;
 	bclear_t			bclear;
 	char			*string = "TS ABLE BAKER";

 	retval = stobclear(string, &bclear, NEW_LABEL, &error);
 	retval = bclearvalid(&bclear);
 	printf("Return value = %d¥n", retval);
 }

printf(1) 文によって、次のように出力されます。1 は、認可上限が有効であることを示します。-1 は、label_encodings ファイルがアクセス不可であることを示します。0 は、ラベルが有効でないか、プロセスの機密ラベルが認可上限より優位でなく sys_trans_label 特権が有効でないことを示します。

Return value = 1

プロセス認可上限の変換

ラベルと同じように、認可上限もバイナリ、ASCII、16 進のいずれかで示すことができます。カーネル内部では、認可上限はすべてバイナリ形式で格納されます。バイナリは、プログラムインタフェース上でやり取りされる認可上限に使用される形式です。

バイナリと ASCII

次の例は、バイナリ認可上限を長形式の語句を使用した、 ASCII に変換します。TS A B で動作しているプロセスは、バイナリ認可上限に同等で、特権を必要としません。


注 -

ASCII の入出力形式、規則、およびフラグの詳細は、「バイナリと ASCII」を参照してください。


#include <tsol/label.h>
 main()
 {
 	int			retval, length = 0;
 	bclear_t			pclear;
 	char			*string = (char *)0;

 	retval = getclearance(&pclear);
 	retval = bcleartos(&pclear, &string, length, LONG_WORDS);
 	printf("Process clearance = %s¥n", string);
 }

printf(1) 文によって、次のように出力されます。

Process clearance = TS ABLE BAKER

次の例は、プロセスのラベルを 5 文字以内にクリッピング (長さを変更) します。クリッピングは、pclear 内の文字数が指定された長さを超える場合に行われます。

#include <tsol/label.h>

 main()
 {
 	int			retval;
 	bclear_t			pclear;
 	char			*string = (char *)0;

 	retval = getclearance(&pclear);
 	string = sbcleartos(&pclear, 5);
 	printf("Clipped process clearance = %s¥n", string);
 }

printf 文によって、次のように出力されます。<- は、名前がクリッピングされたことを示します。この <- は、2 文字としてクリッピング後の文字数に含まれます。

Clipped process clearance = TS<-

次の例は、ASCII 文字列をバイナリ認可上限に変換します。

#include <tsol/label.h>

 main()
 {
 	int			retval, error;
 	bclear_t			bclear;
 	char			*labelstring = "TS ABLE BAKER";

 	retval = stobclear(labelstring, &bclear, NEW_LABEL, &error);
 	if (retval == 0)
 		printf("Error = %d¥n", error);
 	else
 		printf("Retval = %d¥n", retval);
 }

printf(1) 文により、次のように出力されます。

Retval = 1

バイナリと 16 進

バイナリから 16 進への変換には、通常ルーチンと再入可能ルーチンの 2 種類のルーチンがあります。どちらのルーチンも、変換後の文字列へのポインタを返します。また、渡された認可上限が bclear_t 型でなければ NULL を返します。

通常ルーチン

次の例は、バイナリのプロセス認可上限を 16 進に変換し、再び元に戻します。

#include <tsol/label.h>

 main()
 {
 	int			retval;
 	bclear_t			hclear;
 	char			*string ;

 	retval = getclearance(&hclear);

 	if((string = bcleartoh(&hclear)) != 0)
 		printf("Hex string = %s¥n", string);

 	retval = htobclear(string, &hclear);
 	printf("Return Value = %d¥n", retval);
 }

最初の printf(1) 文により、バイナリの認可上限が次のように 16 進形式で出力されます。

0xClearance hexadecimal value

2 番目の printf 文により、次のように出力されます。0 以外は、変換が成功したことを示します。

Return Value = 1

再入可能ルーチン

再入可能 (MT - 安全、マルチスレッドに対して安全) ルーチン bcleartoh_r(3) は、返される値に対する記憶領域の割り当てと開放を必要とします。h_alloc(3) ルーチンは、変換されるラベルの型 (この場合は 16 進形式) にあわせて適切なサイズの記憶領域を割り当てるのに使用されます。

が 16 進値である場合は、定義された認可上限 (SUN_CLR_ID) が 16 進に変換されることを表します。

次の例は、変換の型に対し記憶領域を割り当て、バイナリのプロセス認可上限を 16 進に変換し、最後に記憶領域を解放します。

#include <tsol/label.h>

 main()
 {
 	bclear_t			 hclear;
 	char			*string, *hex;

 	getclearance(&hclear);
 	hex = h_alloc(SUN_CLR_ID);
 	if((string = bcleartoh_r(&hclear, hex)) != 0);
 		printf("Hex string = %s¥n", string);

 	h_free(hex);
 }

printf(1) 文により、次のように 16 進形式でバイナリ認可上限が出力されます。


Hex string = 0x0006cc0000000000000000000000000000000000000 
000000003ffffffffffff0000