JavaScript is required to for searching.
ナビゲーションリンクをスキップ
印刷ビューの終了
Oracle Solaris 11 セキュリティーサービス開発ガイド     Oracle Solaris 11.1 Information Library (日本語)
このドキュメントの評価
search filter icon
search icon

ドキュメントの情報

はじめに

1.  Oracle Solaris の開発者向けセキュリティー機能 (概要)

2.  特権付きアプリケーションの開発

特権付きアプリケーション

特権について

管理者が特権を割り当てる方法

特権の実装方法

許可された特権セット

継承可能な特権セット

制限特権セット

実効特権セット

スーパーユーザーモデルと特権モデルの互換性

特権の種類

特権を使用したプログラミング

特権のデータ型

特権インタフェース

setppriv(): 特権設定用

priv_str_to_set(): 特権マッピング用

特権のコーディング例

スーパーユーザーモデルでの特権の囲い込み

最小特権モデルでの特権の囲い込み

特権付きアプリケーション開発のガイドライン

承認について

3.  PAM アプリケーションおよび PAM サービスの記述

4.  GSS-API を使用するアプリケーションの記述

5.  GSS-API クライアント例

6.  GSS-API サーバー例

7.  SASL を使用するアプリケーションの記述

8.  Oracle Solaris 暗号化フレームワークの紹介

9.  ユーザーレベルの暗号化アプリケーションの記述

10.  Oracle Solaris 鍵管理フレームワークの紹介

A.  開発者のためのセキュアコーディングガイドライン

B.  C ベース の GSS-API プログラム例

C.  GSS-API リファレンス

D.  OID の指定

E.  SASL ソースコード例

F.  SASL リファレンス

用語集

索引

ドキュメントの品質向上のためのご意見をください
簡潔すぎた
読みづらかった、または難し過ぎた
重要な情報が欠けていた
内容が間違っていた
翻訳版が必要
その他
Your rating has been updated
貴重なご意見を有り難うございました!

あなたの貴重なご意見はより良いドキュメント作成の手助けとなります 内容の品質向上と追加コメントのためのアンケートに参加されますか?

特権を使用したプログラミング

このセクションでは、特権を操作するためのインタフェースについて説明します。特権プログラミングインタフェースを使用するには、次のヘッダーファイルが必要になります。

#include <priv.h>

また、特権付きアプリケーションにおける特権インタフェースの使用例も示します。

特権のデータ型

特権インタフェースで使用される主なデータ型は、次のとおりです。

特権インタフェース

次の表は、特権を使用するためのインタフェースの一覧です。この表に続いて、主な特権インタフェースのいくつかについて説明します。

表 2-1 特権を使用するためのインタフェース

目的
関数
補足説明
特権セットの取得と設定
setppriv()getppriv() はシステム呼び出しです。priv_ineffect()priv_set() は簡易操作用のラッパーです。
特権の特定と変換
これらの関数は、指定された特権または特権セットを特定の名前または数字にマッピングします。
特権セットの操作
これらの関数は、特権のメモリー割り当て、テスト、および各種セット操作に関する機能を提供します。
プロセスフラグの取得と設定
PRIV_AWARE プロセスフラグは、プロセスが特権を理解するのか、それともプロセスがスーパーユーザーモデルの下で実行されるのかを示します。PRIV_DEBUG は特権のデバッグ時に使用されます。
低レベルの資格操作
これらのルーチンは、デバッグ、低レベルのシステム呼び出し、およびカーネル呼び出しを行う際に使用されます。

setppriv(): 特権設定用

特権設定用の主要関数は、 setppriv() です。その構文は次のとおりです。

int setppriv(priv_op_t op, priv_ptype_t which, \
const priv_set_t *set);

op は、実行する特権操作を表します。op パラメータには、次の 3 つの値のいずれかを指定できます。

which には、変更する特権セットの種類を指定します。次のいずれかを指定します。

set には、変更操作で使用される特権を指定します。

さらに、簡易関数 priv_set() が提供されています。

priv_str_to_set(): 特権マッピング用

これらの関数は、特権名を数値にマッピングする場合に役立ちます。 priv_str_to_set() は、このファミリの一般的な関数です。priv_str_to_set() の構文は次のとおりです。

priv_set_t *priv_str_to_set(const char *buf, const char *set, \
const char **endptr);

priv_str_to_set() は特権名の文字列を引数に取りますが、その文字列は buf に指定されます。priv_str_to_set() が返す特権値のセットは、4 つの特権セットのいずれかと組み合わせることができます。**endptr は、構文解析エラーのデバッグ時に使用できます。

buf には次のキーワードを含めることができます。

特権のコーディング例

このセクションでは、スーパーユーザーモデルを使って特権を囲い込みする方法と、最小特権モデルを使って特権を囲い込みする方法を比較します。

スーパーユーザーモデルでの特権の囲い込み

次の例では、スーパーユーザーモデルで特権操作を囲い込みする方法を示します。

例 2-1 スーパーユーザー特権の囲い込み例

/* Program start */
uid = getuid();
seteuid(uid);

/* Privilege bracketing */
seteuid(0);
/* Code requiring superuser capability */
...
/* End of code requiring superuser capability */
seteuid(uid);
...
/* Give up superuser ability permanently */
setreuid(uid,uid);

最小特権モデルでの特権の囲い込み

この例では、最小特権モデルで特権操作を囲い込みする方法を示します。この例では、次のように仮定します。

コードリストに続いて、この例の説明があります。


注 - このソースコード例は、Oracle ダウンロードセンターからダウンロードすることも可能です。http://www.oracle.com/technetwork/indexes/downloads/sdlc-decommission-333274.html を参照してください。


例 2-2 最小特権の囲い込み例

1  #include <priv.h>
2  /* Always use the basic set. The Basic set might grow in future
3   * releases and potentially retrict actions that are currently
4   * unrestricted */
5  priv_set_t *temp = priv_str_to_set("basic", ",", NULL);

6  /* PRIV_FILE_DAC_READ is needed in this example */
7  (void) priv_addset(temp, PRIV_FILE_DAC_READ);

8  /* PRIV_PROC_EXEC is no longer needed after program starts */
9  (void) priv_delset(temp, PRIV_PROC_EXEC);

10 /* Compute the set of privileges that are never needed */
11  priv_inverse(temp);

12  /* Remove the set of unneeded privs from Permitted (and by
13   * implication from Effective) */
14  (void) setppriv(PRIV_OFF, PRIV_PERMITTED, temp);

15  /* Remove unneeded priv set from Limit to be safe */
16  (void) setppriv(PRIV_OFF, PRIV_LIMIT, temp);

17  /* Done with temp */
18  priv_freeset(temp);

19  /* Now get rid of the euid that brought us extra privs */
20  (void) seteuid(getuid());

21  /* Toggle PRIV_FILE_DAC_READ off while it is unneeded */
22  priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_FILE_DAC_READ, NULL);

23  /* Toggle PRIV_FILE_DAC_READ on when special privilege is needed*/
24  priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_FILE_DAC_READ, NULL);

25  fd = open("/some/retricted/file", O_RDONLY);

26  /* Toggle PRIV_FILE_DAC_READ off after it has been used */
27  priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_FILE_DAC_READ, NULL);

28  /* Remove PRIV_FILE_DAC_READ when it is no longer needed */
29  priv_set(PRIV_OFF, PRIV_ALLSETS, PRIV_FILE_DAC_READ, NULL);

このプログラムでは、temp という名前の変数が定義されます。temp 変数は、このプログラムで不要な特権のセットを判定します。まず 5 行目で、temp が基本特権セットを含むように定義されています。7 行目で、file_dac_read 特権が temp に追加されています。proc_exec 特権は、新しいプロセスに対して exec(1) を実行するために必要ですが、このプログラムでは許可されていません。したがって、9 行目で、proc_exectemp から削除されています。これで、exec(1) コマンドを使って新しいプロセスを実行できなくなります。

この時点で temp に含まれているのは、このプログラムが必要とする特権だけ、つまり基本セット + file_dac_read - proc_exec です。11 行目では、priv_inverse() 関数が、temp の反転を計算し、temp の値をその反転値にリセットしています。この反転は、指定されたセット (この場合は temp) を可能なすべての特権のセットから差し引いた結果です。11 行目を実行した結果、temp には、このプログラムが必要としない特権が含まれています。14 行目で、temp によって定義された不要な特権が、許可されたセットから差し引かれています。この削除の結果、それらの特権が実効セットからも削除されます。16 行目で、不要な特権が制限セットから削除されています。18 行目で、temp 変数は解放されています。というのも、temp は以後使用しないからです。

このプログラムは特権に対応しています。したがって、このプログラムでは setuid は使用されず、20 行目で実効 UID がユーザーの実際の UID にリセットされています。

22 行目では、file_dac_read 特権を実効セットから削除することで、この特権が無効化されています。実際のプログラムでは、file_dac_read が必要とされる前に、何らかの処理が行われます。このサンプルプログラムでは、25 行目でファイルを読み取る際に file_dac_read が必要となります。 したがって、24 行目で file_dac_read が有効化されています。 ファイルの読み取り後すぐに、file_dac_read が実効セットから再度削除されています。すべてのファイルの読み取りが完了すると、すべての特権セット内の file_dac_read をオフにすることで、file_dac_read が完全に削除されています。

次の表は、プログラム実行中の特権セットの遷移を示したものです。行番号が表示されています。

表 2-2 特権セットの遷移

ステップ
temp セット
許可された特権セット
実効特権セット
制限特権セット
初期状態
all
all
all
5 行目 – temp を基本特権に設定します。
基本
all
all
all
7 行目 – file_dac_readtemp に追加します。
基本 + file_dac_read
all
all
all
9 行目 – proc_exectemp から削除します。
基本 + file_dac_readproc_exec
all
all
all
11 行目 – temp を反転します。
すべて – (基本 + file_dac_readproc_exec)
all
all
all
14 行目 – 許可されたセット内の不要な特権をオフにします。
すべて – (基本 + file_dac_readproc_exec)
基本 + file_dac_readproc_exec
基本 + file_dac_readproc_exec
all
16 行目 – 制限セット内の不要な特権をオフにします。
すべて – (基本 + file_dac_readproc_exec)
基本 + file_dac_readproc_exec
基本 + file_dac_readproc_exec
基本 + file_dac_readproc_exec
18 行目 – temp ファイルを解放します。
基本 + file_dac_readproc_exec
基本 + file_dac_readproc_exec
基本 + file_dac_readproc_exec
22 行目 – 必要になるまで file_dac_read をオフにします。
基本 – proc_exec
基本 – proc_exec
基本 + file_dac_readproc_exec
24 行目 – 必要に応じて file_dac_read をオンにします。
基本 + file_dac_readproc_exec
基本 + file_dac_readproc_exec
基本 + file_dac_readproc_exec
27 行目 – read() 操作後にfile_dac_read をオフにします。
基本 – proc_exec
基本 – proc_exec
基本 + file_dac_readproc_exec
29 行目 – 不要になった file_dac_read をすべてのセットから削除します。
基本 – proc_exec
基本 – proc_exec
基本 – proc_exec