man手冊頁之access函數

摘要:本文描述的是Linux手冊頁中access函數的使用說明,使用access函數檢查實際用戶的文件訪問權限.原文來自:http://www.kernel.org/doc/man-pages/.

access函數

NAME
    accesss - 檢查實際用戶的文件訪問權限
SYNOPSIS
    #include <unistd.h>
    int access(const char *pathname, int mode);
    #include <fcntl.h>           /* Definition of AT_* constants */
    #include <unistd.h>
    int faccessat(int dirfd, const char *pathname, int mode, int flags);
   Feature Test Macro Requirements for glibc (see feature_test_macros(7)):
       faccessat():
           Since glibc 2.10:
               _XOPEN_SOURCE >= 700 || _POSIX_C_SOURCE >= 200809L
           Before glibc 2.10:
               _ATFILE_SOURCE
DESCRIPTION
    access()函數檢查進程是否可以訪問文件路徑名.如果文件名是一個符號鏈接,那它是個引用.
    訪問權限將以指定的模式mode去檢查,模式mode的值可以是F_OK,或者是和R_OK、W_OK及X_OK做按位或運算組合. F_OK是測試文件是否存在,R_OK,W_OK和X_OK分別用來測試文件是否具有可寫、可讀和可執行權限.當用戶對文件執行某個操作時(如打開),內核以進程的有效用戶ID和有效組ID爲基礎執行其訪問權限測試.有時,進程也希望按其實際用戶ID和實際組ID來測試其訪問能力.
    如果一個進程已超級用戶權限運行,那它可以執行任何一個可運行文件.
  faccessat()
    除了在描述上有些差異外,faccessat()系統調用和access()完全相同.
    如果參數pathname是一個相對路徑名,那它是相對於dirfd的路徑,而不是相對應於當前工作目錄.
    如果參數pathname是一個相對路徑名,並且參數dirfd指定爲AT_FDCWD,那pathname被解析爲相對應的當前工作目錄.
    如果參數pathname是一個絕對路徑名,參數dirfd被忽略.
    flags是由下例幾個值做或運算的組合:
AT_EACCESS 使用有效用戶ID和有效用戶組ID執行訪問權限,默認情況下,faccessat()是以實際用戶ID和實際組ID來檢查其訪問能力.
AT_SYMLINK_NOFOLLOW 如果參數pathname是一個符號鏈接,不要放棄處理,而是返回一個關於符號鏈接本身的信息.

RETURN VALUE
    成功返回0(所有檢測權限都通過檢查),失敗返回-1(模式mode至少有一訪問權限被禁止),出錯設置errno指明出錯信息.
ERROES
  access()將會失敗,如果出現下一情況:

    EACCES 參數pathname所指定的文件不符合測試權限要求.
    ELOOP 參數pathname有太多連接符.
    ENAMETOOLONG 參數panthname太長.
    ENOTDIR 參數panthname是一個目錄.
    EROFS 在一個只讀的文件上測試寫入權限.
  access()可能會失敗,如果出現下一情況:
    EFAULT 參數panthname指針超出可存取內存空間.
    EINVAL 指定的參數mode不正確.
    EIO IO存取出錯.
    ENOMEM 主內存存儲空間不足.
    ETXTBSY 在一個正在運行的文件上測試寫入權限.
CONFORMING TO
       SVr4, 4.3BSD, POSIX.1-2001.
NOTES
    警告:使用access()做用戶認證方面的判斷要特別小心,例如在access()後再做open()的空文件可能會造成系統安全上的問題.因爲用戶可能利用檢查和打開中間這個短暫的時間間隔來操作它.所以用戶應該避免這種情況.(例子已說明,一個更安全的選擇是暫時切換進程的有效用戶ID到實際用戶ID,然後再調用open().)
    access()取消對符號鏈接的檢查,如果需要對一個符號鏈接進行檢查,請使用faccessat()函數,將標誌位置爲AT_SYMLINK_NOFOLLOW.
    如果任意一位訪問權限被禁止,access()將出錯,儘管其他訪問權限位通過.
    如果進程有適當的訪問權限,比如超級用戶,在POSIX.1-2001規定中,允許檢查一個沒有設置可執行位的文件,且成功返回,但在Linux下不行.文件所在的每一個目錄都可以訪問,纔可以使用access()檢查文件的訪問權限.如果文件所在目錄不能訪問,則調用access()函數將會失敗,儘管待檢查的文件有訪問的權限.
    access()只作權限的檢查, 並不理會文件狀態或文件內容,因此,如果一目錄表示爲"可寫入",表示可以在該目錄中建立新文件等操作,而非意味此目錄可以被當做文件處理.例如:你會發現DOS  
的文件都具有"可執行"權限,但用execve()執行時則會失敗.
    這些調用在NFSv2文件系統用戶ID映射中可能無法正常工作,因爲檢查UID映射文件時,UID映射文件是在服務器端的,而在客戶端是不可見的,類似的問題也可能會出現在掛載的文件系統中.
  C library/kernel ABI differences
    原始的faccessat()系統調用只需要前三個參數,標誌AT_EACCESS 和AT_SYMLINK_NOFOLLOW是在glibc函數庫中使用,如果指定其中一個標誌,那函數庫調用fstastat(2)函數來檢查文件的訪問權限.
  Glibc notes
    在老版本的內核系統中,如果沒有指定AT_EACCESS和AT_SYMLINK_NOFOLLOW標誌的話,函數faccessat()是不可用的,glibc函數庫將會調用access().當參數pathname是相對路徑時,glibc函數庫會在/proc/self/fd中構造一個符號鏈接作爲對應的dirfd參數.
BUGS
    在內核2.4(或更早)處理X_OK檢查不是很成熟,對一個沒有目錄的文件,如果所有用戶的可執行權限都被禁止,當access()指定mode爲X_OK來檢查文件權限時,將會返回-1,如果指定mode爲R_OK或者W_OK,則access()返回0.在早期的內核2.6中也有類似的問題.
    在內核2.6.20版本前,如果是底層的掛載文件系統,這些函數調用都忽略了標誌MS_NOEXEC,但從內核2.6.20標誌MS_NOEXEC纔得到重視.

END

筆者:個人能力有限,只是學習...讀者若發現文中錯誤,敬請提出.

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------勿在浮沙築高臺,靜下心來,慢慢地沉澱---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

發佈了33 篇原創文章 · 獲贊 44 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章