Обнаружение значения FileSystemRights, которое не определено в перечислении


Я написал приложение, которое проверяет все разрешения файловой системы на каталог.

Каталог имеет ряд правил доступа (типа FileSystemAccessRule).

Каждое правило доступа имеет свойство FileSystemRights, которое является перечислением флагов.

При запуске этого приложения я постоянно сталкиваюсь с FileSystemRights значением 268435456 (которое приходит к 0x10000000 в шестнадцатеричном виде).

Это значение просто не появляется в перечислении! Это на самом деле выше, чем самое высокое значение одиночного флага (Synchronize, имеющее значение из 0x100000).

Кто-нибудь знает, что это такое?

3 8

3 ответа:

См.http://cjwdev.wordpress.com/2011/06/28/permissions-not-included-in-net-accessrule-filesystemrights-enum/

С этой страницы:

Используя .NET, вы можете подумать, что определение того, какие разрешения являются назначение директории / файла должно быть достаточно простым, так как имеется Перечисление FileSystemRights определено, которое, по-видимому, содержит все возможные разрешение, которое может иметь файл/каталог и вызов AccessRule.FileSystemRights возвращает комбинацию этих значений. Однако вскоре вы столкнетесь с некоторыми разрешениями, где значение в это свойство не соответствует ни одному из значений в FileSystemRights Перечисление (я бы хотел, чтобы они не называли некоторые свойства с тем же именем как тип, но эй).

Конечным результатом этого является то, что для некоторых файлов/каталогов вы просто не удается определить, какие разрешения им назначены. Если вы это сделаете AccessRule.FileSystemRights.ToString тогда для этих значений все, что вы видите это число, а не а описание (например, изменить, удалить, FullControl прием). Общие числа, которые вы можете увидеть:

-1610612736, -536805376 и 268435456

Чтобы выяснить, каковы эти разрешения на самом деле, вам нужно посмотреть на какие биты задаются, когда вы рассматриваете это число как 32 отдельных бита а не как целое число (поскольку целые числа имеют длину 32 бита), и сравнить их к этой диаграмме: http://msdn.microsoft.com/en-us/library/aa374896 (v=против 85).aspx

Так, например, -1610612736 имеет Первый БИТ и третий бит набора, что означает, что это GENERIC_READ в сочетании с GENERIC_EXECUTE. Теперь эти общие разрешения можно преобразовать в конкретный файл системные разрешения, которым они соответствуют.

Здесь вы можете увидеть, какие разрешения сопоставляет каждое универсальное разрешение: http://msdn.microsoft.com/en-us/library/aa364399.aspx . просто осознавайте что STANDARD_RIGHTS_READ, STANDARD_RIGHTS_EXECUTE и STANDARD_RIGHTS_WRITE - это все то же самое (не знаю почему, кажется странно для меня) и на самом деле все равны FileSystemRights.Значение ReadPermissions.

От https://social.technet.microsoft.com/Forums/windowsserver/en-US/5211a077-63fc-4016-b750-25bf26b3ad15/why-does-getacl-return-filesystemrights-that-are-invalid-in-filesystemaccesrule-used-with-setacl?forum=winserverpowershell

268435456-FullControl

-536805376-Изменить, Синхронизировать

-1610612736-ReadAndExecute, Synchronize

(чтобы сэкономить вам немного математики)

Вот мое решение для исправления FileSystemRights, чтобы они соответствовали перечислению.

Об этом есть несколько документов. Ссылки включены в код.
    public static FileSystemRights FileSystemRightsCorrector(FileSystemRights fsRights, bool removeSynchronizePermission = false)
    {
        // from: https://msdn.microsoft.com/en-us/library/aa374896%28v=vs.85%29.aspx
        const int C_BitGenericRead = (1 << 31);
        const int C_BitGenericWrite = (1 << 30);
        const int C_BitGenericExecute = (1 << 29);
        const int C_BitGenericAll = (1 << 28);


        // https://msdn.microsoft.com/en-us/library/aa364399.aspx
        // FILE_GENERIC_READ = FILE_READ_ATTRIBUTES | FILE_READ_DATA | FILE_READ_EA | STANDARD_RIGHTS_READ | SYNCHRONIZE 
        // FILE_GENERIC_WRITE = FILE_APPEND_DATA | FILE_WRITE_ATTRIBUTES | FILE_WRITE_DATA | FILE_WRITE_EA | STANDARD_RIGHTS_WRITE | SYNCHRONIZE
        // FILE_GENERIC_EXECUTE  = FILE_EXECUTE | FILE_READ_ATTRIBUTES | STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE 

        //from Winnt.h
        //#define STANDARD_RIGHTS_READ             (READ_CONTROL)
        //#define STANDARD_RIGHTS_WRITE            (READ_CONTROL)
        //#define STANDARD_RIGHTS_EXECUTE          (READ_CONTROL)

        // from: https://msdn.microsoft.com/en-us/library/windows/desktop/aa379607%28v=vs.85%29.aspx
        // READ_CONTROL = "The right to read the information in the object's security descriptor,"
        // ==> STANDARD_RIGHTS_READ, STANDARD_RIGHTS_WRITE, STANDARD_RIGHTS_EXECUTE == FileSystemRights.ReadPermissions

        // translation for the generic rights to the FileSystemRights enum
        const FileSystemRights C_FsrGenericRead = FileSystemRights.ReadAttributes | FileSystemRights.ReadData | FileSystemRights.ReadExtendedAttributes | FileSystemRights.ReadPermissions | FileSystemRights.Synchronize;
        const FileSystemRights C_FsrGenericWrite = FileSystemRights.AppendData | FileSystemRights.WriteAttributes | FileSystemRights.WriteData | FileSystemRights.WriteExtendedAttributes | FileSystemRights.ReadPermissions | FileSystemRights.Synchronize;
        const FileSystemRights C_FsrGenericExecute = FileSystemRights.ExecuteFile | FileSystemRights.ReadAttributes | FileSystemRights.ReadPermissions | FileSystemRights.Synchronize;

        if (((int)fsRights & C_BitGenericRead) != 0)
        {
            fsRights |= C_FsrGenericRead;
        }

        if (((int)fsRights & C_BitGenericWrite) != 0)
        {
            fsRights |= C_FsrGenericWrite;
        }

        if (((int)fsRights & C_BitGenericExecute) != 0)
        {
            fsRights |= C_FsrGenericExecute;
        }

        if (((int)fsRights & C_BitGenericAll) != 0)
        {
            fsRights |= FileSystemRights.FullControl;
        }

        // delete the 4 highest bits if present
        fsRights = (FileSystemRights)((int)fsRights & ~(C_BitGenericRead | C_BitGenericWrite | C_BitGenericExecute | C_BitGenericAll));

        // for some purposes the "Synchronize" flag must be deleted
        if (removeSynchronizePermission == true)
        {
            fsRights = (FileSystemRights)((int)fsRights & ~((int)FileSystemRights.Synchronize));
        }

        return fsRights;
    }