この節では、Trusted Solaris 7 に装備されている、実行可能ファイルの特権セットの設定と取得を行うユーザーコマンドとプログラミングインタフェースについて説明します。強制特権と許容特権が設定されていない場合、デフォルトでは強制特権セットと許容特権セットには none が入っています。
実行前にファイル特権セットを設定した場合、その新しい特権セットは、その時点から有効になり、現在の実行に対するプロセス特権セットの計算に使用されます。実行中にファイル特権セットを設定した場合、次の実行までは無効で、現在の実行に対するプロセス特権セットには影響を与えません。
コマンド行からファイル特権セットの設定と取得を行うには、setfpriv(1) と getfpriv(1) を使用します。setfpriv(1) は、file_setpriv 特権を必要とするので、このコマンドをプロファイルシェルから実行するときに、この特権を使用します。setfpriv(1) をスクリプトで使用する方法の詳細は、「スクリプトを使用したファイル特権の割り当て」を参照してください。
このコマンド行は、この章の例の executable (実行可能ファイル) に対して、ファイル特権セットを設定します。複数の特権を指定する場合は、スペースを入れずにコンマで区切ります。スペースを使用したい場合は、("privilege1, privilege2") のように特権名を二重引用符で囲んでください。
phoenix% setfpriv -s -f file_setpriv -a file_mac_write,proc_setid,file_setpriv executable
このコマンド行は、ファイル特権セットが設定されているかどうかの確認のため出力します。
phoenix% getfpriv executable executable FORCED: file_setpriv ALLOWED: file_mac_write,file_setpriv,proc_setid
この節で説明する特権マクロとシステムコールは、ファイル特権セットの取得と設定を行います。次のプログラムには、この章のすべての例で使用されるヘッダーファイルと変数宣言が含まれます。また、execfile (実行可能ファイル) に対するファイル特権セットの設定と取得を行うコードも含まれます。この execfile は、後で exec() により使用され、プロセス特権セットに何が起きるかを表示します。
setfpriv(1) システムコールは、execfile に強制特権セットと許容特権セットを設定し、file_setpriv 特権を要求します。file_setpriv 特権は executable の強制セットに含まれるため、この特権は実行中に許可セットで使用できます。デフォルトでは、有効セットは許可セットと同じです。また、すべての有効特権は、特権のブラケット化の準備のために明示的にオフにされるまでは、オンのままです。このコードにおける file_setpriv の使用は、特権のブラケット化 (「有効な特権のブラケット化」を参照) が有効にならないかぎり、セキュリティガイドラインに従いません。
/* cc priv.c -o executable -ltsol */ #include <tsol/priv.h> #include <sys/types.h> #include <errno.h> #include <stdio.h> /* 大域変数*/ extern int errno; char buffer [3*1024]; main() { char *priv_names = "file_mac_write$proc_setid"; char *string; char *privilege; char *file = "/export/home/zelda/executable"; char *execfile = "/export/home/zelda/execfile"; priv_set_t priv_set, priv_get, permitted_privs, saved_privs; int length = sizeof(buffer); int retval; pid_t pid; /* 後で exec() に使用する */ char *argv[8] = {"execfile"}; /* 特権セットのデータ構造を初期化する */ PRIV_EMPTY(&priv_get); PRIV_EMPTY(&priv_set); /* 許容された特権をオフ(無効) にする。詳細は本文を参照 */ retval = setfpriv(execfile, PRIV_SET, PRIV_ALLOWED, &priv_get);
/* 特権セット構造体内で、Priv_names に指定した特権を */ /* 表明し、execfile に割り当てる。特権の表明のやり方については */ /* 本文を参照 */ if((string = str_to_priv_set(priv_names, &priv_set, "$")) != NULL) printf("string = %s errno = %d¥n", string, errno); retval = setfpriv(execfile,PRIV_ON, PRIV_ALLOWED, &priv_set); /* 許容された特権セットに特権が含まれていることを確認する */ retval = getfpriv(execfile, PRIV_ALLOWED, &priv_get); priv_set_to_str(&priv_get, '$', buffer, &length); printf("execfile Allowed = %s¥n", buffer); /* 特権セットのデータ構造体を初期化する */ PRIV_EMPTY(&priv_set); PRIV_EMPTY(&priv_get); /* 特権セット構造体で file_mac_write を表明する */ PRIV_ASSERT(&priv_set, PRIV_FILE_MAC_WRITE); /* 強制された特権セットを execfile ファイルに対して有効にする */ retval = setfpriv(execfile, PRIV_ON, PRIV_FORCED, &priv_set); /* 強制された特権セットに特権が含まれていることを確認する */ retval = getfpriv(execfile, PRIV_FORCED, &priv_get); priv_set_to_str(&priv_get, `$', buffer, &length); printf("execfile Forced =%s¥n", buffer); }
printf 文により、execfile に対するファイル特権セットが次のように出力されます。
execfile Allowed = file_mac_write$proc_setid
execfile Forced = file_mac_write
この出力は、ドル記号 (「$」) を使用して許容される特権を分離しています。この区切り文字は、priv_set_to_str(3) に対する呼び出しで指定されます。セット内に特権が 1 つしかない場合には、区切り文字は使用しません。
強制セットは、許容セットのサブセットです。強制セット内のすべての特権は、許容セットがクリアされるときにクリアされます。許容セットはデフォルトでは none ですが、何も設定されていない状態から開始することがわかるように、初めにこれをクリアする習慣をつけるとよいでしょう。強制セットを設定する場合は、設定前に必ず許容セットのクリアと設定を行なってください。次のコードを実行すると、実行後、許容セットと強制セットは両方とも none になります。
PRIV_EMPTY(&priv_set); retval = setfpriv(execfile, PRIV_SET, PRIV_ALLOWED, &priv_set);
特権セット構造で特権を表明するには、PRIV_ASSERT マクロまたは str_to_priv_set(3) ルーチンを使用できます。表明する特権が 2 つ以上ある場合には、1 つの文で表明できる str_to_priv_set() が便利です。一方、PRIV_ASSERT は、セット内で表明する特権ごとに呼び出す必要があります。このコードは、許容セットに対し str_to_priv_set() ルーチンを使用し、強制セットに対し PRIV_ASSERT を使用しています。str_to_priv() ルーチンは、成功時には NULL を返し、失敗時には priv_names で渡した文字列を返します。
if((string = str_to_priv_set(priv_names, &priv_set, "$")) != NULL) printf("string = %s errno = %d¥n", string, errno); PRIV_EMPTY(&priv_set); PRIV_ASSERT(&priv_set, PRIV_FILE_MAC_WRITE);
次の例は、プロセス特権セットを操作します。これらの操作を実行する前に、ファイルとプロセスの特権セットを確認してください。プロセスセットは、「プロセス特権セット」のアルゴリズムから計算されます。
executable Allowed = file_mac_write$file_setpriv$proc_setid
executable Forced = file_setpriv
Permitted = file_mac_write$file_setpriv$proc_setid
Effective = file_mac_write$file_setpriv$proc_setid
Saved = file_mac_write$proc_setid
Inheritable = file_mac_write&file_setpriv$proc_setid