Encountering a FileSystemRights value that isn't defined in enumeration
Asked Answered
E

3

11

I've written an application that examines all of the file system permissions on a directory.

A directory has a number of access rules (of type FileSystemAccessRule).

Each access rule has a property FileSystemRights, which is a flag enumeration.

When running this, I keep encountering a FileSystemRights value of 268435456 (which comes to 0x10000000 in hexadecimal).

This value just doesn't appear in enumeration! It's actually higher than the highest single flag value (Synchronize, having a value of 0x100000).

Does anyone know what this is?

Extraction answered 14/3, 2012 at 1:47 Comment(0)
O
14

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

From that page:

Using .NET you may think that determining which permissions are assigned to a directory/file should be quite easy, as there is a FileSystemRights Enum defined that seems to contain every possible permission that a file/directory can have and calling AccessRule.FileSystemRights returns a combination of these values. However, you will soon come across some permissions where the value in this property does not match any of the values in the FileSystemRights Enum (I do wish they wouldn’t name some properties with the same name as a Type but hey).

The end result of this is that for some files/directories you simply cannot determine which permissions are assigned to them. If you do AccessRule.FileSystemRights.ToString then for these values all you see is a number rather than a description (e.g Modify, Delete, FullControl etc). Common numbers you might see are:

-1610612736, –536805376, and 268435456

To work out what these permissions actually are, you need to look at which bits are set when you treat that number as 32 separate bits rather than as an Integer (as Integers are 32 bits long), and compare them to this diagram: http://msdn.microsoft.com/en-us/library/aa374896(v=vs.85).aspx

So for example, -1610612736 has the first bit and the third bit set, which means it is GENERIC_READ combined with GENERIC_EXECUTE. So now you can convert these generic permissions into the specific file system permissions that they correspond to.

You can see which permissions each generic permission maps to here: http://msdn.microsoft.com/en-us/library/aa364399.aspx. Just be aware that STANDARD_RIGHTS_READ, STANDARD_RIGHTS_EXECUTE and STANDARD_RIGHTS_WRITE are all the same thing (no idea why, seems strange to me) and actually all equal the FileSystemRights.ReadPermissions value.

Octangle answered 14/3, 2012 at 1:54 Comment(0)
B
3

In some cases the FileSystemRights have bits set which do not contain any meaningfull information and can get removed. Some have a format which is not supported by the FileSystemRights class but can be converted. (The NTFS driver understands both formats). There are several documents at microsoft regarding this:

Based on this the method FileSystemRightsCorrector() cleans this data up make it "readable". There is a paremter bool removeSynchronizePermission = false which should be used with the default value, except you have the need to remove this flag also.

    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 purpouses the Synchronize flag needs to be deleted.
        // If you don't have trouble with that flag leave it untouched!
        if (removeSynchronizePermission == true)
        {
            fsRights = (FileSystemRights)((int)fsRights & ~((int)FileSystemRights.Synchronize));
        }

        return fsRights;
    }
Bilateral answered 20/11, 2015 at 14:52 Comment(6)
I have encountered ACEs with GENERIC_ACCESS set in the wild. So your workaround only carries so far ... the .NET Framework is clearly not prepared to create ACEs which can full well occur in the wild (and by my observations can also be read by the respective classes).Anchylose
Haven't ever seen that. In what .h file is it defined?Bilateral
Sorry, GENERIC_ALL (0x10000000) is what I meant. That is, I have seen ACLs with ACEs which used the generic form instead of the concrete form. But the (public) ctors for FileSystemAccessRule prevent you from using anything outside the range defined for the enum ☹Anchylose
Found an actual solution to the problem, obviously your solution does work, but it mangles the access mask beforehand (which is what I wanted to avoid).Anchylose
The solution for me ...Anchylose
@Anchylose great job!Bilateral
C
2

from 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 (0x10000000)

-536805376 - Modify, Synchronize (0xE0010000)

-1610612736 - ReadAndExecute, Synchronize (0xA0000000)

(to save you some math)

Containment answered 18/11, 2014 at 0:29 Comment(1)
This is wrong. There's a difference between generic and standard access masks and you're ignoring it and pretending they're one and the same. They aren't. FullControl corresponds to 0x1F01FF, look it up. However 268435456 == 0x10000000 == GENERIC_ALL is the symbolic name corresponding to the first value. The meaning is the same and if you ran GENERIC_ALL through MapGenericMask you'd end up with 0x1F01FF for a file, but they're still not identical. And while this may seem like nitpicking, in security these details do matter.Anchylose

© 2022 - 2024 — McMap. All rights reserved.