Object Manager
Windows 裡頭,諸如 process/thread/file/timer...等都是以 object 來表示。當我們開啟一個 file 時,會給予我們要存取的權限,如讀/寫/讀寫…等,這個權限就會跟 file object 中的 access control list (ACL) 做比對,如果權限 OK 的話,則會傳回一個 handle,以後要對 file 存取就透過這個 handle。上面所述的安全驗證只在第一次 open/create 的時候,當傳回 handle 之後,權限的檢查就透過 handle 中的 access mask 來判斷。這個 access mask 就是當初在開啟或新增 file object 時我們指定的。
當使用者登入系統後,使用者程序上會附一個 token,裡頭部份註明了:
安全識別碼
群組識別碼
特權
主群組
預設 ACL
雖然此 token 是附在 process 上的,但是 process 仍然要透過 handle(token 本身也是 object)才能修改它。這是因為有可能 process 並沒有權限修改自己本身的 access token。
而每一個 object 分為 header 與 body,header 中包含了:
object name 物件名稱
object directory 物件階層的結構
security descriptor 安全描述子,指向一個 ACL
quota charges 使用此物件時要花費掉多少 resource (memory)
open handle count 一個 handle 已經對此物件開啟的次數
open handles list 指向一個 process list,裡頭是所有開啟此物件的 processes
object type 指向 type object
reference count 被核心物件參考的次數
object header 存放每個物件共同的資料結構,但允許不同物件有不同的值。而 type object 存放每一個 object 中共同的資料部份。因此假設我們有五個 process object,則它們都會有一個指標指向 process type object。
security descriptor 指向一個 ACL,它是一個 list,其中每個元素叫 access control entry (ACE)。每個 ACE 中都指明針對特定群組所能給的權限,如「允許-DEVEC群組-讀取資料」。
那這個安全檢查動作誰來做?答案是 object manager。回到前頭說的,當使用者要開啟檔案時,object manager 會將 user process 中的 ACL 與 file object 中 security descriptor 所指向的 ACL 做比對。它由第一個比對到最後一個,只要有一個權限符合就跳出。接著 user process 會得到一個指向此 file object 的 handle,它存放在自己 process 中的 handle table。這個 handle 佔 8 bytes,後 4 bytes 存放著 access mask。之後存取檔案就利用這個 handle。
由於 ACL 是由第一個比對到最後一個,因此如果前後兩個 ACE 的權限互相衝突的話,是以前面的 ACE 為準。如第 1 個 ACE 允許我存取,但第 10 個 ACE 不允許我存取,這情況下我還是可以存取的。不過 ACL 中,關於不允許(拒絕)的存取會放在比較前面的 ACE。
這邊有個問題,object manager 負責 open/create object 這樣的工作嗎?如果是如此,那 object manager 就要瞭解所有物件實作的細節囉?其實不是,object manager 不用瞭解物件是如何產生的。當一個 object 被新建出來的時候,就會向 object manager 登記一些 object method,這些 method 包含 open/close/delete…等。object manager 只要透過呼叫這些 method 即可。
每個 process 都有自己的 handle table,它採用三層式表格。某一個 process A 的 handle 可以被複製給 process B,則 A 跟 B 就可以共用這個 handle 指向的 object。
object name 是以階層方式存放。object manager 有其管理的 object domain,而 I/O manager 也有其管理的 object domain。這邊 I/O manager 就稱作 secondary object manager。如 object manager 可管理到 \Device 底下的 Floppy0 這個 device object。device object 會有一個 parse method。在做名稱搜尋時,object manager 會去呼叫 parse method,並將必要參數傳給它。
比如我們想存取 A:\abc\abc.txt,A: 事實上是一個 symbolic link,它指向 \Device\Floppy0。Floppy0 是一個 device object,裡頭有 parse method。此時 object manager 會呼叫 parse method 並將 \abc\abc.txt 此名稱傳給它。parse method 是由 I/O system 提供,它會要求適當的 file system 找到檔案所在位置。
留言
張貼留言