0

共有フォルダーの 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 を適切に取得する方法です。

4

1 に答える 1

0

SECURITY_DESCRIPTOR は不透明なハンドルとして扱う必要があります。行で行ったようにキャストすることはできません:

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

上記のキャストを実行すると、自己相対の SECURITY_DESCRIPTOR があるため、すべての所有者、グループ、DACL、および SACL 情報が失われますが、構造の定義とともにデータをマーシャリングしていません。

さまざまな API 呼び出し (GetSecurityDescriptorDacl など) の宣言を変更して、ref SECURITY_DESCRIPTOR ではなく byte[] を取得し、ADsSecurityUtility から受け取った byte[] を渡すだけです。

于 2013-03-14T12:58:22.957 に答える