我正在尝试获取共享文件夹的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 ?
必须将SECURITY_DESCRIPTOR视为不透明句柄。不能像在
中那样强制转换为1。 sd = (SECURITY_DESCRIPTOR)Marshal.PtrToStructure(ptr,
typeof(SECURITY_DESCRIPTOR));
当您执行上述强制转换时,您丢失了所有的所有者,组,DACL和SACL信息,因为您有一个自相关的SECURITY_DESCRIPTOR,但您没有将数据与您的结构定义一起封送。
简单地改变你的各种API调用的声明(即GetSecurityDescriptorDacl等),以一个字节[]而不是一个ref SECURITY_DESCRIPTOR,并传递你从adssecurityyutility收到的字节[]。