2013-03-14 5 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 в порядке, у меня нет проблем с этим. Затем я пытаюсь получить DACL и SACL из SD.

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 АСЕ. Таким образом, кажется, что SACL содержит все из них. Однако MS не рекомендует использовать эти свойства. Вместо этого следует использовать GetSecurityDescriptorDacl и GetSecurityDescriptorSacl. Поэтому я использую их. И посмотрите, что количество ACE в DACL равно 0, а количество ACE в SACL также равно 0.

Итак, вопрос: как правильно получить все ACE из дескриптора безопасности?

ответ

0

Вы должны обработать SECURITY_DESCRIPTOR как непрозрачный дескриптор. Вы не можете бросить в один, как вы сделали на линии:

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

Когда ты вышеупомянутую бросание вы потеряли все права владельца, группы, DACL и SACL информацию, поскольку у вас есть автономный родственник SECURITY_DESCRIPTOR но ты не сортируют данные вместе с вашим определением структуры.

Просто измените свои объявления различных вызовов API (например, GetSecurityDescriptorDacl и т. Д.), Чтобы взять байт [], а не ref SECURITY_DESCRIPTOR и передать в байт [], который вы получили из ADsSecurityUtility.

Смежные вопросы