名前


capget, capset - ケーパビリティを設定/取得する

書式


#undef _POSIX_SOURCE #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 0x19980330

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

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

hdrversion フィールドに他のバージョンが指定された場合、 この呼び出しは EINVAL を返し、このフィールドを _LINUX_CAPABILITY_VERSION に設定する。

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

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

返り値


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

エラー


EFAULT 不正なメモリアドレス。 hdrpdatap のどちらもが NULL である。
EINVAL 引き数のどれかが無効である。
EPERM 「許可ケーパビリティセット」にケーパビリティを追加しようとしているか、 もしくは「許可ケーパビリティセット」に含まれないケーパビリティを 「実効ケーパビリティセット」や「継承可能ケーパビリティセット」に セットしようとしている。
EPERM 呼び出し元が自分以外のスレッドのケーパビリティを capset() を使って修正しようとしたが、十分な特権がなかった。 CAP_SETPCAP ケーパビリティが必要である。 (バージョン 2.6.11 より前のカーネルには、 このケーパビリティを持たないスレッドが pid フィールドに 0 でない値 (つまり、0 の代わりに getpid(2) が返す値) を指定して自分自身のケーパビリティを変更しようとした場合にも、 このエラーが発生するというバグがあった。)
ESRCH そのようなスレッドが存在しない。

準拠


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

備考


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

関連項目


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

openSUSE Logo

コンテンツ