EN JA
SETUID(2)
SETUID(2) FreeBSD System Calls Manual SETUID(2)

名称

setuid, seteuid, setgid, setegidユーザ ID とグループ ID を設定する

ライブラリ

Standard C Library (libc, -lc)

書式

#include < sys/types.h>
#include < unistd.h>

int
setuid( uid_t uid);

int
seteuid( uid_t euid);

int
setgid( gid_t gid);

int
setegid( gid_t egid);

解説

setuid() システムコールは、現在のプロセスの実ユーザ ID と実効ユーザ ID と退避ユーザ ID を指定した値に設定します。 setuid() システムコールが許容されるのは、指定の ID がプロセスの実ユーザ ID または実効ユーザ ID に等しい場合、または実効ユーザ ID がスーパユーザのものと等しい場合です。

setgid() システムコールは、現在のプロセスの実グループ ID と実効グループ ID と退避グループ ID を指定した値に設定します。 setgid() システムコールが許容されるのは、指定の ID がプロセスの実グループ ID または実効グループ ID に等しい場合、または実効ユーザ ID がスーパユーザのものと等しい場合です。

seteuid() システムコール ( setegid()) は、現在のプロセスの実効ユーザ (グループ ID) を設定します。実効ユーザ ID は、実ユーザ ID または退避ユーザ ID ( intro(2)execve(2) を参照 ) の値に設定できます。これを利用し、ユーザ ID 設定された実行可能ファイルの実効ユーザ ID を実ユーザ ID に切り替えた後に、ユーザ ID 設定の値に戻ることで、元の権限を得ることができます。同じように、実効グループ ID は、実グループ ID または退避グループ ID の値に設定できます。

戻り値

Upon successful completion, the value 0 is returned; otherwise the value -1 is returned and the global variable errno is set to indicate the error.

エラー

本システムコールは、次の場合に失敗します:
[ EPERM]
ユーザがスーパユーザでない場合、または指定された uid がその実 ID、実効 ID、または退避 ID でない場合。

規格

setuid() と setgid() システムコールは、 IEEE Std 1003.1-1990 (“POSIX.1”) 仕様と互換性があります。ただし、 _POSIX_SAVED_IDS は、付録 B.4.2.2 の許可された拡張で定義されていません。 seteuid() と setegid() システムコールは、 _POSIX_SAVED_IDS の POSIX コンセプトを基礎にして拡張してあり、規格の将来の改定用に提案されています。

歴史

setuid() と setgid() 関数は、 Version 7 AT&T UNIX で登場しました。

セキュリティに関する考察

ファイルへの読み込みと書み込み許可は、 open(2) が呼ばれた時に判断されます。一度ファイル記述子がオープンされると、権限を落してもそのプロセスの読み込みまたは書み込み許可には影響しません。指定されたユーザ ID に、そのファイルへの読み込みまたは書み込み許可がなくともです。通常これらのファイルは、新しいプロセスの実行時にオープンされたままとなり、その結果、ユーザがもしかすると要注意であるデータを読んだり修正したりできてしまいます。

これらのファイルが exec(3) 呼び出しの後でもオープンされたままにされるのを防ぐには、必ず close-on-exec フラグを設定してください:

void 
pseudocode(void) 
{ 
 int fd; 
 /* ... */ 
 
 fd = open("/path/to/sensitive/data", O_RDWR); 
 if (fd == -1) 
  err(1, "open"); 
 
 /* 
  * close-on-exec フラグの設定;さらなる情報は fcntl(2) を参照。 
  */ 
 if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1) 
  err(1, "fcntl(F_SETFD)"); 
 /* ... */ 
 execve(path, argv, environ); 
}
June 4, 1993 FreeBSD