筆者在《Linux ACL 權限》一文中介紹了 Linux ACL 權限的基本用法,本文筆者將嘗試探究 ACL 中的基本概念和實現原理,但願可以經過進一步的加深對 Linux 權限系統的理解。說明:本文的演示環境爲 ubuntu 16.04。html
ACL 的類型linux
ACL 條目
一個 ACL 由多個 ACL 條目組成。一個 ACL 條目指定一個用戶或者一組用戶對所關聯對象的讀、寫、執行權限。下圖展現了 ACL 條目的類型及含義:web
ACL 定義的權限是 ugo 權限的超集。算法
文件的 ugo 權限老是與對應的 ACL 條目保持一致。修改文件的 ugo 權限會致使修改相關的 ACL 條目,一樣的,修改這些 ACL 條目會致使修改對應的 guo 權限。ubuntu
一個文件的 access ACL 會在經過 creat()、mkdir()、mknod()、mkfifo() 和 open() 函數建立該文件時被初始化。函數
若是一個目錄被設置了 default ACL,那麼將會由文件建立函數的 mode 參數和目錄的 default ACL 共通決定新文件的 ACL 權限:spa
說明:此時 umask 被忽略。.net
若是一個目錄沒有被設置 default ACL,那麼將由文件建立函數的 mode 參數和 umask 共同決定新文件的 ACL 權限:翻譯
當一個進程訪問(讀、寫、執行)一個被 ACL 保護的文件時,文件權限檢查的算法決定了是否受權給進程訪問該文件。
下面咱們以 下面咱們以僞代碼的方式來解釋文件權限檢查的算法。
第一步:if 進程的 effective user ID 與文件 owner 匹配
if ACL 的 ACL_USER_OBJ 條目包含了請求所需的權限,此時就被受權訪問文件
else 訪問被拒絕
第二步:else if 進程的 effective user ID 匹配文件 ACL 權限中任何一個 ACL_USER 條目中的 user
if 匹配的 ACL_USER 條目和 ACL_MASK 條目包含了請求所需的權限,此時就被受權訪問文件
else 訪問被拒絕
第三步:else if 進程的 effective group ID 或者任何一個補充的(supplementary) group ID 匹配文件的 group 或 ACL 權限中任何一個 ACL_GROUP 條目的 group
if ACL 權限包含 ACL_MASK 條目
if ACL_MASK 條目和匹配的任何 ACL_GROUP_OBJ 或 ACL_GROUP 條目包含了請求所需的權限,此時就被受權訪問文件
(註釋:ACL_MASK 與其它項是 and 的關係,用來控制最大權限)
else 訪問被拒絕
else (注意:沒有 ACL_MASK 條目,就沒有 ACL_GROUP 條目)
if ACL_GROUP_OBJ 條目包含了請求所需的權限,此時就被受權訪問文件
else 訪問被拒絕
第四步:else if ACL_OTHER 條目包含了請求所需的權限,此時就被受權訪問文件
第五步:else 訪問被拒絕3d
有兩種格式來描述 ACL 條目,分別是長格式和短格式。它們很是相似,都是經過兩個冒號把一個 ACL 條目分爲三個部分:
ACL 條目的類型:ACL 條目 qualifier:權限信息
咱們在前面已經介紹過 ACL 條目的類型,權限信息就是用 rwx 來表示的信息,不支持某個權限的話可使用 - 表示。這裏介紹一下 ACL 條目 qualifier(不知道該咋翻譯這貨)。
其中的用戶標識符能夠是用戶名也能夠是 user ID,組標識符能夠是組名也能夠是 group ID。
下面是一組長格式的示例:
user::rw-
user:tester:rw- #effective:r--
group::r--
group:tester1:rw- #effective:r--
mask::r--
other::r--
下面是一組短格式的示例:
u::rw-,u:tester:rw-,g::r--,g:tester1:rw-,m::r--,o::r--
g:tester1:rw,u:tester:rw,u::wr,g::r,o::r,m::r
前文咱們的重點是介紹 ACL 權限的基本用法。有了本文前面介紹的基礎內容,咱們就能夠解釋前文中出現的一些比較怪異的現象。
建立用戶 tester, tester1:
$ sudo adduser tester $ sudo adduser tester1
先建立文件 aclfile,檢查其默認的 ACL 權限信息:
而後爲 tester 用戶賦予讀寫 aclfile 文件的權限:
$ setfacl -m u:tester:rw aclfile
此時查看 aclfile 文件的權限:
$ ll aclfile
貌似並無發生什麼變化,只是在描述權限的地方多出了一個 "+" 號。下面再看看 acl 權限:
$ getfacl aclfile
上圖的黃框中出現了 ACL_MASK 條目,這就是咱們的第一個問題:
**************************************************************
咱們並無顯式的設置 ACL_MASK 條目,爲何它出現了?
An ACL that contains entries of ACL_USER or ACL_GROUP tag types must contain exactly one entry of the ACL_MASK tag type. If an ACL contains no entries of ACL_USER or ACL_GROUP tag types, the ACL_MASK entry is optional.
上面的解釋大意是當添加了 ACL_USER 或 ACL_GROUP 後,必須有一個對應的 ACL_MASK 條目。在當前的狀況下,ACL_MASK 是被自動建立的,它的權限被設置成了 group(實際上是 group class) 的權限即 rw-。
**************************************************************
下面咱們接着更新 aclfile 的 ACL 權限:
$ setfacl -m u:tester:rwx,g:tester1:r aclfile
查看文件權限:
在修改了 tester 的權限並添加了 tester1 group 的權限後,咱們看到的組權限竟然變成了 rwx !
這是咱們的第二個問題:
**************************************************************
爲何 aclfile 文件的組權限變成了 rwx?
這是由於咱們設置了 u:tester:rwx 致使的:
在設置了 ACL 權限後,group 顯示的權限爲 ACL_MASK 條目中的權限。而 ACL_MASK 條目中的權限表示 ACL_USER、ACL_GROUP_OBJ 和 ACL_GROUP 條目可以被授予的最大權限,因此當 tester 被設置了 rwx 權限時,ACL_MASK 條目中的權限也發生了相應的變化。並最終致使咱們看到了上面的結果:-rw-rwxr--+。
**************************************************************
接下來咱們看看 acl 權限:
用戶 tester 具備 aclfile 的讀寫執行權限,tester1 group 具備 aclfile 的讀權限,可是這裏的 mask 卻變成了 rwx!
這是咱們的第三個問題:
**************************************************************
上面的設置並無顯式的指定 mask 項,爲何 mask 的值卻變了?
其實咱們在第二個問題中已經回答了這個問題,是由於 tester 被設置了 rwx 權限,最終致使 ACL_MASK 條目中的權限也發生了相應的變化。
這裏咱們能夠思考一下:ACL 權限中爲何須要 ACL_MASK 條目?
這是一個須要從長計議的話題,咱們應該從 ACL 權限與 ugo 權限的對應提及。在 ugo 權限模型中,定義了 3 個 class 來表示 owner、group、other 的權限。Owner class 表示文件全部者具備的訪問權限,group class 表示 owner group 具備的訪問權限,other class 表示其它用戶所具備的訪問權限。在沒有顯式的設置 ACL 權限時,文件的 ACL 權限與 ugo 權限的對應關係以下圖所示:
咱們把重點放在 group class 上,此時 group class 的權限和 owner group 的權限是徹底同樣的。
可是在咱們添加了 ACL 權限以後,狀況就變得有些複雜了:
此時 group class 中還可能包含 ACL_USER 和 ACL_GROUP 條目中的權限。這樣就會出現 owner group 權限與 group class 不一致的狀況。
解決的辦法就是爲 ACL 權限引入 ACL_MASK 條目:
**************************************************************
最後咱們再來設置一下 aclfile 的 mask:
$ setfacl -m mask::r aclfile
$ getfacl aclfile
ACL 權限的最後一道防線就是 mask 。它決定了一個用戶或組可以獲得的最大的權限。上圖中的 #effective 顯示了對應行的實際權限。文件權限也反應了上面的變化:
咱們的最後一個問題:
**************************************************************
爲何須要 effective 權限?
ACL_MASK 條目 限制的是 ACL_USER、ACL_GROUP_OBJ 和 ACL_GROUP 條目的最大權限,因此在應用了 ACL_MASK 條目後,須要經過 effective 權限來得到 ACL_USER、ACL_GROUP_OBJ 和 ACL_GROUP 條目的真正權限(如上圖所示)。當 ACL_USER、ACL_GROUP_OBJ 和 ACL_GROUP 條目包含不包含在 ACL_MASK 條目中的權限,則該條目後面會有一個 "#" 號和字符串 "effective",以及該條目的有效訪問權限。
可是 mask 只對 ACL_USER、ACL_GROUP_OBJ 和 ACL_GROUP 條目有影響(紅框中的內容),對 owner 和 other 的權限是沒有任何影響的。
**************************************************************
本文先介紹了 ACL 權限中的基本概念,而後解釋了筆者在使用 ACL 權限過程當中碰到的一些疑問。但願這些內容能夠幫助你們更好的理解和使用 ACL 權限。