2013-03-14 96 views
0

我想獲取共享文件夾的ACL。獲取安全描述符的代碼如下:無法正確訪問ACL

private static SECURITY_DESCRIPTOR GetSecurityDescriptor(string path) 
{ 
    var sdUtil = new ADsSecurityUtility(); 
    Byte[] temp = (Byte[])sdUtil.GetSecurityDescriptor(path, (int)ADS_PATHTYPE_ENUM.ADS_PATH_FILESHARE, (int)ADS_SD_FORMAT_ENUM.ADS_SD_FORMAT_RAW); 
    IntPtr ptr = (IntPtr)0; 
    SECURITY_DESCRIPTOR sd; 
    try 
    { 
     ptr = Marshal.AllocHGlobal(temp.Length); 
     Marshal.Copy(temp, 0, ptr, temp.Length); 
     sd = (SECURITY_DESCRIPTOR)Marshal.PtrToStructure(ptr, typeof(SECURITY_DESCRIPTOR)); 
     return sd; 
    } 
    catch (Exception) 
    { 
     throw new Exception("Couldn't get security descriptor"); 
    } 
    finally 
    { 
     Marshal.FreeHGlobal(ptr); 
    } 
} 

SD是好的,我沒有問題。 然後我試圖從SD中獲得DACL和SACL。

private static List<ACL> GetAcls(SECURITY_DESCRIPTOR sd) 
{ 
    List<ACL> result = new List<ACL>(2); 
    ACL temp = new ACL(); 
    int daclPresent = 0; 
    int daclDefaulted = 0; 
    try 
    { 
     int res = PInvoke.GetSecurityDescriptorDacl(ref sd, ref daclPresent, ref temp, ref daclDefaulted); 
     result.Add(temp); 
     temp = new ACL(); 
    } 
    catch (Exception) { } 
    try 
    { 
     int res = PInvoke.GetSecurityDescriptorSacl(ref sd, ref daclPresent, ref temp, ref daclDefaulted); 
     result.Add(temp); 
    } 
    catch (Exception) { } 
    return result; 
} 

外部函數被定義爲以下:

[DllImport("advapi32.dll")] 
    public static extern int GetSecurityDescriptorDacl(
     [MarshalAs(UnmanagedType.Struct)] ref SECURITY_DESCRIPTOR pSecurityDescriptor, 
     ref int lpbDaclPresent, 
     [MarshalAs(UnmanagedType.Struct)] ref ACL pDacl, 
     ref int lpbDaclDefaulted 
    ); 

    [DllImport("advapi32.dll")] 
    public static extern int GetSecurityDescriptorSacl(
     [MarshalAs(UnmanagedType.Struct)] ref SECURITY_DESCRIPTOR pSecurityDescriptor, 
     ref int lpbDaclPresent, 
     [MarshalAs(UnmanagedType.Struct)] ref ACL pDacl, 
     ref int lpbDaclDefaulted 
    ); 

當我檢查SD實例的屬性我看到以下:

sd.Dacl 
{Permission.ACL} 
    AceCount: 83886080 
    AclRevision: 169 
    AclSize: 1281 
    Sbz1: 0 
    Sbz2: 21 

sd.Sacl 
{Permission.ACL} 
    AceCount: 6 
    AclRevision: 20 
    AclSize: 9961474 
    Sbz1: 0 
    Sbz2: 2359297 

在總ACL包含6級的ACE。所以看來SACL包含了所有這些。不過MS不推薦使用這些屬性。應該使用GetSecurityDescriptorDacl和GetSecurityDescriptorSacl。所以我使用它們。並且看到DACL中ACE的計數是0,並且SACL中ACE的計數也是0.

所以問題是:如何從安全描述符中正確獲取所有ACE?

回答

0

您必須將SECURITY_DESCRIPTOR視爲不透明句柄。你可以不投給一個你已經上線完成:

sd = (SECURITY_DESCRIPTOR)Marshal.PtrToStructure(ptr, 
      typeof(SECURITY_DESCRIPTOR)); 

當你失去了所有的所有者,組,DACL和SACL信息上面鑄,因爲你有一個自相關SECURITY_DESCRIPTOR但你並不是將數據與您對結構的定義一起編組。

只需更改各種API調用(即GetSecurityDescriptorDacl等)的聲明以獲取字節[]而不是參考SECURITY_DESCRIPTOR並傳遞從ADsSecurityUtility收到的byte []。