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

名前

       access, faccessat, faccessat2 - ユーザーのファイルへのアクセス権をチェックする

書式

       #include <unistd.h>

       int access(const char *pathname, int mode);

       #include <fcntl.h>           /* AT_* 定数の定義 */
       #include <unistd.h>

        int faccessat(int dirfd, const char *pathname, int mode, int flags);
                       /* But see C library/kernel differences, below */

       int faccessat2(int dirfd, const char *pathname, int mode, int flags);

   glibc 向けの機能検査マクロの要件 (feature_test_macros(7)  参照):

       faccessat():
           glibc 2.10 以降:
               _POSIX_C_SOURCE >= 200809L
           glibc 2.10 より前:
               _ATFILE_SOURCE

説明

       access()   は、呼び出し元プロセスがファイル  pathname にアクセスできるかどうかをチェックす
       る。 pathname がシンボリックリンクの場合、シンボリックリンクは展開される。

       mode はチェックを行うアクセス権を指定するもので、その値は F_OK、 もしくは R_OK, W_OK, X_OK
       の 1個以上のビット単位の論理和から構成されるマスクである。 F_OK はファイルが存在するかどう
       かのみを検査する。 R_OK, W_OK, X_OK は、ファイルが存在して、それぞれ読み込み、書き込み、実
       行の許可があるか を検査する。

       The  check is done using the calling process's real UID and GID, rather than the effective
       IDs as is done when actually  attempting  an  operation  (e.g.,  open(2))   on  the  file.
       Similarly, for the root user, the check uses the set of permitted capabilities rather than
       the set of effective capabilities; and for non-root users, the check uses an empty set  of
       capabilities.

       This  allows  set-user-ID programs and capability-endowed programs to easily determine the
       invoking user's authority.   In  other  words,  access()   does  not  answer  the  "can  I
       read/write/execute  this  file?"  question.   It  answers  a  slightly different question:
       "(assuming I'm a setuid binary) can  the  user  who  invoked  me  read/write/execute  this
       file?",  which  gives set-user-ID programs the possibility to prevent malicious users from
       causing them to read files which users shouldn't be able to read.

       呼び出し元プロセスが特権プロセス (つまり、プロセスの実 UID が 0) の場合、 通常のファイルに
       対する  X_OK のチェックは、そのファイルの所有者、グループ、他人のいずれかの 実行許可が有効
       になっていれば成功する。

   faccessat()
       faccessat() は access() と全く同様に動作するが、以下で説明する点が異なる。

       pathname で指定されたパス名が相対パスの場合、このパス名はファイルディスクリプター dirfd が
       参照するディレクトリに対する相対パスと解釈される  (access() に相対パス名を渡した場合のよう
       に、呼び出したプロセスのカレントワーキングディレクトリに対する相対パスではない)。

       pathname で指定されたパス名が相対パスで、 dirfd が特別な値 AT_FDCWD の場合、 (access()  と
       同様に)  pathname は呼び出したプロセスのカレントワーキングディレクトリに対する相対パスと解
       釈される。

       pathname で指定されたパス名が絶対パスの場合、 dirfd は無視される。

       flags は以下に示す値の 0 個以上の OR (論理和) をとって作成される。

       AT_EACCESS
              アクセスチェックを実行ユーザー/グループ        ID        を使って行う。デフォルトで
              は、faccessat() は (access() と同様に) 実 ID を使用する。

       AT_SYMLINK_NOFOLLOW
              pathname がシンボリックリンクの場合、リンクの展開を行わない。代わりに、リンク自身の
              情報を返す。

       faccessat() の必要性についての説明については openat(2) を参照。

   faccessat2()
       The  description  of  faccessat()   given  above  corresponds  to  POSIX.1  and   to   the
       implementation  provided  by  glibc.   However,  the glibc implementation was an imperfect
       emulation (see BUGS)  that papered over the fact that the raw  Linux  faccessat()   system
       call  does  not  have  a  flags argument.  To allow for a proper implementation, Linux 5.8
       added the faccessat2() system call, which supports the flags argument and allows a correct
       implementation of the faccessat()  wrapper function.

返り値

       成功した場合  (要求した全てについて許可が得られたか、  modeF_OK でファイルが存在した場
       合)、ゼロが返される。 エラーの場合 (mode  の少なくとも一つのビットで要求した許可がなかった
       場合、  modeF_OK でファイルが存在しなかった場合、他のエラーが起こった場合)、-1 が返さ
       れ、 errno が適切に設定される。

エラー

       access() と faccessat() は以下の場合に失敗する。

       EACCES 要求されたアクセスは そのファイル自身に拒否されたか pathname へ至るまでディレクトリ
              のいずれかに対する検索許可       (search       permission)       が得られなかった。
              (path_resolution(7)  も参照のこと)

       ELOOP  pathname を解決するときに、解決すべきシンボリックリンクが多すぎた。

       ENAMETOOLONG
              pathname が長過ぎる。

       ENOENT pathname を構成するパスのいずれかが、存在しないか、 参照先のない (dangling)  シンボ
              リックリンクになっている。

       ENOTDIR
              pathname のディレクトリ部分が実際にはディレクトリでない。

       EROFS  読み込み専用 (read-only) のファイルシステムに対して書き込み許可を 要求した。

       access() と faccessat() は以下の理由により失敗することがある。

       EFAULT pathname がアクセス可能なアドレス空間の外を指している。

       EINVAL mode に不正な値が指定された。

       EIO    I/O エラーが発生した。

       ENOMEM カーネルに十分なメモリーがない。

       ETXTBSY
              実行中のファイルに対して書き込みを要求した。

       faccessat() では以下のエラーも発生する。

       EBADF  dirfd が適切なファイルディスクリプターでない。

       EINVAL flags に無効なフラグが指定された。

       ENOTDIR
              pathname  が相対パスで、  dirfd  がディレクトリ以外のファイルを参照しているファイル
              ディスクリプターである。

バージョン

       faccessat()  はバージョン 2.6.16 で Linux に追加された。 ライブラリによるサポートは  glibc
       バージョン 2.4 で追加された。

       faccessat2() は Linux 5.8 で追加された。

準拠

       access(): SVr4, 4.3BSD, POSIX.1-2001, POSIX.1-2008.

       faccessat(): POSIX.1-2008.

       faccessat2() は Linux 固有である。

注意

       警告:  あるユーザーが、例えば open(2) によるアクセスが可能かどうかを、 (実際に行う前に) こ
       れらのシステムコールを使ってチェックするのは、セキュリティホールの原因になる。なぜなら
       チェックをしてから  実際にファイルのオープン操作をする間の短い間隔を悪用できるからである。
       この理由があるので、このシステムコールを使うのは避けるべきである。 (ここで説明した例の場合
       には、より安全な方法としては、  そのプロセスの実効ユーザー ID を実ユーザー ID に一時的に切
       り替えてから open(2) を呼び出す方法がある。)

       access() は常にシンボリックリンクの展開を行う。 シンボリックリンクのアクセス許可を確認する
       必要がある場合は、 AT_SYMLINK_NOFOLLOW フラグ付きで faccessat() を使うこと。

       mode で指定されたアクセス種別のいずれか一つでも拒否されると、 たとえ mode で指定された他の
       アクセス種別が許可されたとしても、 これらのシステムコールはエラーを返す。

       POSIX.1-2001 では、  呼び出し元プロセスが適切な特権を持っている場合  (つまり、スーパーユー
       ザーの場合)、 たとえファイルの実行許可ビットが全くセットされていなくても X_OK のチェックと
       して成功を返す実装が認められている。 Linux はこのようにはなっていない。

       pathname のプレフィックスを構成するディレクトリの全てに対して 検索アクセス (すなわち、実行
       アクセス) が許可された場合にのみ、 ファイルはアクセス可能となる。 いずれかのディレクトリが
       アクセス不可の場合、 ファイル自身のアクセス許可に関わらず、 access() は失敗する。

       アクセスビットのみがチェックされ、ファイルの種類や内容はチェックされない。  従って、ディレ
       クトリが書き込み可能となった場合は、ディレクトリに  ファイルを作成することが可能なことを意
       味するのであり、ディレクトリに ファイルとして書き込むことができるわけではない。 同様に DOS
       のファイルは「実行可能」と判断されるが、 execve(2)  コールは失敗するだろう。

       これらのシステムコールは、 UID マッピングを使用した NFSv2 ファイルシステムでは正常に機能し
       ないかもしれない。なぜならば UID のマッピングはサーバーで 行なわれ、権利のチェックをするク
       ライアントには見えないからである。  (NFS バージョン 3 以降ではサーバー側でチェックが実行さ
       れる。) 同様の問題は FUSE マウントでも起こり得る。

   C ライブラリとカーネルの違い
       生の  faccessat()  システムコールは、最初の  3  つの引数だけを取る。フラグ  AT_EACCESSAT_SYMLINK_NOFOLLOW は実際には faccessat() の glibc のラッパー関数内で実装されている。これ
       らのフラグのいずれかが指定された場合、ラッパー関数は fstatat(2) を使ってアクセス許可の判定
       を行う。ただし「バグ」を参照のこと。

   glibc での注意
       faccessat() が利用できない古いカーネルでは、(フラグ AT_EACCESSAT_SYMLINK_NOFOLLOW が指
       定されていない場合) glibc ラッパー関数は  access()  を使用するモードにフォールバックする。
       pathname が相対パスの場合、 glibc は dirfd 引数に対応する /proc/self/fd のシンボリックリン
       クに基づいてパス名を構成する。

バグ

       Because the Linux kernel's faccessat()  system call does not support a flags argument, the
       glibc  faccessat()   wrapper  function  provided  in  glibc  2.32 and earlier emulates the
       required functionality using a combination of the faccessat()  system call and fstatat(2).
       However,  this  emulation  does not take ACLs into account.  Starting with glibc 2.33, the
       wrapper function avoids this bug by making use of the faccessat2() system call where it is
       provided by the underlying kernel.

       バージョン 2.4 (とそれ以前) のカーネルには、スーパーユーザーでの X_OK のチェックの扱いに奇
       妙な点がある。 ディレクトリ以外のファイルで (ユーザー、グループ、他人の)  全てのカテゴリー
       について 実行許可がない場合、 access()  のチェックで -1 が返るのは modeX_OK だけが指定
       されたときだけであり modeR_OKW_OK が一緒に指定された場合には access()  は  0  を返
       す。  (バージョン 2.6.3 以前の) 初期の 2.6 系のカーネルも 2.4 系のカーネルと同様の動作をす
       る。

       2.6.20 より前のカーネルでは、 これらのシステムコールはファイルが存在するファイルシステムを
       mount(2)  する際に指定された MS_NOEXEC フラグの効果を無視していた。 カーネル 2.6.20 以降で
       は、 MS_NOEXEC フラグは考慮されるようになっている。

関連項目

       chmod(2), chown(2), open(2), setgid(2), setuid(2), stat(2), euidaccess(3), credentials(7),
       path_resolution(7), symlink(7)

この文書について

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