Provided by: manpages-ja-dev_0.5.0.0.20210215+dfsg-1_all bug

名前

       capget, capset - スレッドのケーパビリティを設定/取得する

書式

       #include <sys/capability.h>

       int capget(cap_user_header_t hdrp, cap_user_data_t datap);

       int capset(cap_user_header_t hdrp, const cap_user_data_t datap);

説明

       Linux 2.2 で、スーパーユーザー (root) の権限は、個別のケーパビリティ (capabilities) へと分
       割され、その集合として表現されるようになった。 各スレッドは「実効ケーパビリティ (effective
       capability) の集合」を持ち、 それによって現在どの操作が実行可能かを識別できる。 また、各ス
       レッドは、 「継承可能ケーパビリティ (inheritable capability)  の集合」と  「許可ケーパビリ
       ティ  (permitted capability) の集合」を持つ。 「継承可能ケーパビリティの集合」は execve(2)
       を通じて渡すことができるケーパビリティの集合であり、    「許可ケーパビリティ    (permitted
       capability) の集合」は 実効ケーパビリティや継承可能ケーパビリティとして有効にできる ケーパ
       ビリティを規定するものである。

       この二つのシステムコールはスレッドのケーパビリティを取得したり設定したりするための    生の
       カーネルインターフェースである。  これらのシステムコールは  Linux 特有であるというだけでな
       く、    カーネル    API    は変更されるかもしれず、これらのシステムコールの使用法    (特に
       cap_user_*_t 型という書式) はカーネルのリビジョン毎に拡張されるかもしれないが、 以前のプロ
       グラムはそのまま動作する。

       移植性のあるインターフェースは cap_set_proc(3)  と cap_get_proc(3)  である。  可能ならばア
       プリケーションはこれらの関数を使用すべきである。 アプリケーションに Linux 拡張を使用したい
       場合には、より簡単に 使えるインターフェースである capsetp(3)  と capgetp(3)   を使用すべき
       である。

   現在の詳細
       現在のカーネルの詳細について注意を述べておく。 構造体は以下のように定義される。

           #define _LINUX_CAPABILITY_VERSION_1  0x19980330
           #define _LINUX_CAPABILITY_U32S_1     1

           #define _LINUX_CAPABILITY_VERSION_2  0x20071026
           #define _LINUX_CAPABILITY_U32S_2     2

           typedef struct __user_cap_header_struct {
              __u32 version;
              int pid;
           } *cap_user_header_t;

           typedef struct __user_cap_data_struct {
              __u32 effective;
              __u32 permitted;
              __u32 inheritable;
           } *cap_user_data_t;

       フィールド  effective,  permitted, inheritable は、 capabilities(7) で定義されるケーパビリ
       ティのビットマスクである。 CAP_* はビット番号を表すインデックス値であり、 ビットフィールド
       に OR を行う前に CAP_* の値の分だけビットシフトを行う必要がある。 typedef の方はポインター
       なので、 このシステムコールに渡す構造体を定義するには、 struct __user_cap_header_structstruct __user_cap_data_struct という名前を使用しなければならない。

       カーネル  2.6.25 より前では、バージョン _LINUX_CAPABILITY_VERSION_1 の 32 ビットケーパビリ
       ティが推奨である。 カーネル 2.6.25 以降では、バージョン _LINUX_CAPABILITY_VERSION_2 の  64
       ビットケーパビリティが推奨である。 64 ビットケーパビリティでは datap[0] と datap[1] が使用
       されるのに対し、 32 ビットケーパビリティでは datap[0] だけが使用される。

       これらのシステムコールの挙動に影響があるもう一つの変更点は、 ファイルケーパビリティ  (file
       capabilities)  のカーネルによるサポート (VFS ケーパビリティのサポート) である。 VFS ケーパ
       ビリティのサポートは現在のところコンパイル時のオプションである (カーネル 2.6.24 で追加され
       た)。

       capget()   では、  hdrp->pid のフィールド値にケーパビリティを知りたいプロセスのプロセス ID
       を 指定することで、任意のプロセスのケーパビリティを調べることができる。

   VFS ケーパビリティがサポートされている場合
       VFS ケーパビリティのサポートでは、特権実行ファイルにケーパビリティを  追加するためのファイ
       ル属性メソッドが作成された。  この特権モデルの導入により、あるプロセスにより別のプロセスの
       ケーパビリティ を非同期に設定する機能のカーネルによるサポートは廃止される。 つまり、VFS サ
       ポートでは、 capset()  を呼び出す際に hdrp->pid の値として許されるのは 0 と getpid(2) が返
       す値だけとなる (どちらの値でも等価である)。

   VFS ケーパビリティがサポートされていない場合
       カーネルが VFS ケーパビリティをサポートしていない場合、 hdrppid フィールドが 0  以外で
       あれば、  capset()  の操作対象は pid で指定されたスレッドのケーパビリティになる。 pid が 0
       の場合は呼び出し元のスレッドのケーパビリティが操作対象となる。 pid  がシングルスレッドプロ
       セスを参照している場合、  pid は以前から使われているプロセスID を使って指定できる。 マルチ
       スレッドプロセス内のあるスレッドを対象にする場合は、 gettid(2) が返すスレッドID を用いて指
       定する必要がある。  また、 capset()  では -1 や -1 より小さな値を指定することもできる。 -1
       は呼び出し元と init(1)  を除く全てのスレッドを対象として変更を行うことを、 -1 より小さな値
       は ID が -pid のプロセスグループの全メンバ を対象として変更を行うことを意味する。

       このデータの詳細は capabilities(7)  を参照すること。

返り値

       成功した場合は 0 が返される。エラーの場合は -1 が返され、 errno が適切に設定される。

       hdrp   のフィールド  version  にサポートされていない値が指定された場合、  呼び出しはエラー
       EINVAL で失敗し、 version にカーネル推奨の _LINUX_CAPABILITY_VERSION_? を設定する。 このよ
       うにして、現在の推奨ケーパビリティリビジョンが何かを 調べることができる。

エラー

       EFAULT 不正なメモリーアドレス。 hdrp は NULL であってはならない。 datap に NULL を指定して
              よいのは、ユーザーがカーネルがサポートしている 推奨のケーパビリティバージョンを判定
              しようとしているときだけである。

       EINVAL 引き数のどれかが無効である。

       EPERM  「許可ケーパビリティセット」にケーパビリティを追加しようとしているか、 もしくは「許
              可ケーパビリティセット」に含まれないケーパビリティを 「実効ケーパビリティセット」や
              「継承可能ケーパビリティセット」に セットしようとしている。

       EPERM  呼び出し元が自分以外のスレッドのケーパビリティを capset()  を使って修正しようとした
              が、十分な特権がなかった。 VFS ケーパビリティをサポートしているカーネルでは、  この
              操作が許可されることは決してない。 VFS ケーパビリティをサポートしていないカーネルで
              は、 CAP_SETPCAP ケーパビリティが必要である。 (バージョン 2.6.11 より前のカーネルに
              は、  このケーパビリティを持たないスレッドが pid フィールドに 0 でない値 (つまり、0
              の代わりに getpid(2)  が返す値)  を指定して自分自身のケーパビリティを変更しようとし
              た場合にも、 このエラーが発生するというバグがあった。)

       ESRCH  そのようなスレッドが存在しない。

準拠

       これらのシステムコールは Linux 独自である。

注意

       ケーパビリティを設定したり取得したりする機能のための移植性ある  インターフェースは  libcap
       ライブラリによって提供される。 このライブラリは以下から入手できる:
       ⟨http://git.kernel.org/cgit/linux/kernel/git/morgan/libcap.git

関連項目

       clone(2), gettid(2), capabilities(7)

この文書について

       この man ページは Linux man-pages プロジェクトのリリース 3.79 の一部  である。プロジェクト
       の説明とバグ報告に関する情報は http://www.kernel.org/doc/man-pages/ に書かれている。