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)); 

当您执行上述转换时,您丢失了所有所有者、组、DACL 和 SACL 信息,因为您有一个自相关的 SECURITY_DESCRIPTOR 但您没有将数据与结构的定义一起编组。

只需更改各种 API 调用(即 GetSecurityDescriptorDacl 等)的声明以获取 byte[] 而不是 ref SECURITY_DESCRIPTOR 并传入您从 ADsSecurityUtility 收到的 byte[]。

于 2013-03-14T12:58:22.957 回答