2009-05-26 44 views
5

我在這裏有一個有點晦澀的問題。一個可靠的方法來確定是否繼承ntfs權限

我需要什麼:如果要判斷權限(或,嚴格來說,一個DACL的特定ACE)的文件/文件夾被繼承。

如何試圖解決這個問題:使用WINAPI綁定蟒(win32security模塊,要準確)。這裏是精簡版,就是這樣做的 - 它只是將文件路徑作爲參數,並逐個打印ACE,指出設置了哪些標誌。

#!/usr/bin/env python 
from win32security import * 
import sys 

def decode_flags(flags): 
    _flags = { 
     SE_DACL_PROTECTED:"SE_DACL_PROTECTED", 
     SE_DACL_AUTO_INHERITED:"SE_DACL_AUTO_INHERITED", 
     OBJECT_INHERIT_ACE:"OBJECT_INHERIT_ACE", 
     CONTAINER_INHERIT_ACE:"CONTAINER_INHERIT_ACE", 
     INHERIT_ONLY_ACE:"INHERIT_ONLY_ACE", 
     NO_INHERITANCE:"NO_INHERITANCE", 
     NO_PROPAGATE_INHERIT_ACE:"NO_PROPAGATE_INHERIT_ACE", 
     INHERITED_ACE:"INHERITED_ACE" 
    } 
    for key in _flags.keys(): 
     if (flags & key): 
      print '\t','\t',_flags[key],"is set!" 


def main(argv): 
    target = argv[0] 
    print target 

    security_descriptor = GetFileSecurity(target,DACL_SECURITY_INFORMATION) 

    dacl = security_descriptor.GetSecurityDescriptorDacl() 

    for ace_index in range(dacl.GetAceCount()): 
     (ace_type,ace_flags),access_mask,sid = dacl.GetAce(ace_index) 
     name,domain,account_type = LookupAccountSid(None,sid) 
     print '\t',domain+'\\'+name,hex(ace_flags) 
     decode_flags(ace_flags) 


if __name__ == '__main__': 
    main(sys.argv[1:]) 

夠簡單了 - 獲得一個安全描述符,獲得DACL從它然後通過在DACL將ACE迭代。這裏真正重要的是INHERITED_ACE訪問標誌。應該在ACE被繼承並且沒有明確設置時設置。

當你創建一個文件夾/文件,其ACL獲取與的ACE根據父對象(文件夾)的的ACE,被設置爲傳播給孩子居住。但是,除非您對訪問列表進行任何更改,否則不會設置INHERITED_ACE標誌!但繼承的權限在那裏,他們的工作。

如果你做了任何微小的改變(比如說,向訪問列表中添加一個條目,應用更改並刪除它),該標誌奇蹟般地出現(行爲不會以任何方式改變,儘管它以前工作並且工作正常之後)!我想要的是找到的INHERITED_ACE標誌這種行爲的來源,也許找到另一個可靠的方式來確定是否ACE被繼承與否。

如何重現:

  1. 創建一個對象(文件或文件夾)在Windows資源管理器
  2. 檢查權限,看到他們已經從父對象傳播(使用,比如說,文件的安全選項卡Windows資源管理器的屬性對話框)。
  3. 檢查使用的標誌,例如,我使用(INHERITED_ACE不會在任何的ACE設置)的腳本。
  4. 更改對象的權限(應用更改),甚至將其更改回來。
  5. 檢查標誌(INHERITED_ACE 在那裏)
  6. ..shake在懷疑你的頭(我知道我做的)

對不起,我有點冗長的帖子,希望這至少有一點感。

+0

我已經更新了我的答案。這似乎是與Python庫的問題... – 2009-06-25 09:43:26

回答

0

在我的Win XP家庭版的代碼似乎並沒有在所有的工作:-)

我得到這個堆棧跟蹤:

Traceback (most recent call last):
File "C:\1.py", line 37, in main(sys.argv[1:])
File "C:\1.py", line 29, in main for ace_index in range(dacl.GetAceCount()):

AttributeError: 'NoneType' object has no attribute 'GetAceCount'

你能只是嘗試「微調」的DACL要填補? 我的意思是,如果你知道它會在你稍作修改之後開始工作......以編程的方式做一些小改動,添加一個存根ACE並刪除它。你可以嗎?

UPDATE。我在我的工作機器上(使用Win XP Prof)做了一個C#程序的實驗,我必須告訴你,.net獲取這些安全信息的方法實際上是有效的。所以,當我創建一個新文件時,我的C#程序檢測到ACE是繼承的,而你的python代碼沒有。

這是我跑的樣本輸出:

C:>csharp_tricks.exe 2.txt

FullControl --> IsInherited: True

FullControl --> IsInherited: True

ReadAndExecute, Synchronize --> IsInherited: True


C:>1.py 2.txt

2.txt

BUILTIN\Administrators 0x0

NT AUTHORITY\SYSTEM 0x0

BUILTIN\Users 0x0

我的C#類:

public class InheritedAce 
{ 
    public static string GetDACLReport(string path) 
    { 
     StringBuilder result = new StringBuilder(); 
     FileSecurity fs = new FileSecurity(path, AccessControlSections.Access); 
     foreach (var rule in fs.GetAccessRules(true, true, typeof(SecurityIdentifier)).OfType<FileSystemAccessRule>()) 
     { 
      result.AppendFormat("{0} --> IsInherited: {1}", rule.FileSystemRights, rule.IsInherited); 
      result.AppendLine(); 
     } 

     return result.ToString(); 
    } 
} 

因此,它似乎是在Python pywin32安全庫中的錯誤。也許他們不是在做所有必要的系統調用...

+0

是的,這絕對不會在家庭版中運行 - 據我所知,ntfs的權限被禁用了(所以你因GetSecurityDescriptorDacl而得到None)。您的建議可能是正確的,我應該使用存根ACE來修正DACL。但是,考慮一個事實,即我需要在一個巨大的公司文件服務器上運行這種代碼(想想,數百萬個對象)。如果我(或你)在我的假設中錯了怎麼辦?如果事情搞砸了會怎樣?除非是絕對不可避免的,否則我不會寫這類數據。 – shylent 2009-06-24 21:22:35

1

您可以使用.NET Framework

System.Security.AccessControl 

這包括ACL和DACL和SACL。

+0

不幸的是使用.Net是沒有問題的。無論哪種方式,通過檢查System.Security.AccessControl上的msdn條目,我得出的結論是,本質上它不提供超過C API的額外功能(至少不在我感興趣的領域) - 我的問題是而不是如何檢索繼承標誌 - 這是微不足道的,而是關於INHERITED_ACE標誌的不一致性。 – shylent 2009-06-24 05:58:07

1

我認爲樓主是看到行爲

This newsgroup posting

詳細說明該容器設置的控制標誌可以通過簡單地改變取消勾選並重新勾選GUI中的繼承框。

此外請注意,僅使用Microsoft的工具將ACE添加到DACL也會更改控制標誌。

此外請注意,由於在新聞組發佈中討論過許多微妙的錯誤,因此在繼承時不能依賴GUI,cacls和icacls。

控制繼承的「舊」方式似乎是將容器上的控制標誌與繼承相關的ACE標誌結合使用。

「新」方式不使用容器上的控制標誌,而是使用重複的ACE;一個用於控制對象的訪問,另一個用於控制子對象繼承的內容。

但是,似乎現有的Microsoft工具(如Vista)無法以「新」方式工作,所以當您使用這些工具進行簡單更改時,它會採用舊的方式在容器。

如果創建在Vista上一個新的分區,然後創建一個新的文件夾,然後看標誌和王牌,它會是這個樣子

ControlFlags : 0x8004 
Owner : BUILTIN\Administrators 
Group : WS1\None 
S-1-5-32-544 : BUILTIN\Administrators : 0x0 : 0x0 : 0x1F01FF 
S-1-5-32-544 : BUILTIN\Administrators : 0x0 : 0xB : 0x10000000 
S-1-5-18 : NT AUTHORITY\SYSTEM : 0x0 : 0x0 : 0x1F01FF 
S-1-5-18 : NT AUTHORITY\SYSTEM : 0x0 : 0xB : 0x10000000 
S-1-5-11 : NT AUTHORITY\Authenticated Users : 0x0 : 0x0 : 0x1301BF 
S-1-5-11 : NT AUTHORITY\Authenticated Users : 0x0 : 0xB : 0xE0010000 
S-1-5-32-545 : BUILTIN\Users : 0x0 : 0x0 : 0x1200A9 
S-1-5-32-545 : BUILTIN\Users : 0x0 : 0xB : 0xA0000000 

注意ControlFlags和複製的ACE。