我编写了一个应用程序,它检查目录上的所有文件系统权限。
一个目录具有多个访问规则(类型为FileSystemAccessRule
)。
每个访问规则都有一个属性FileSystemRights
,它是一个标志枚举。
在运行此程序时,我不断遇到一个FileSystemRights
值为268435456
(十六进制为0x10000000
)。
这个值在枚举中根本不存在!它实际上比最高的单个标志值(Synchronize
,其值为0x100000
)还要高。
有人知道这是什么吗?
基于此,方法 FileSystemRightsCorrector()
可以清理此数据并使其“可读”。有一个参数 bool removeSynchronizePermission = false
应该使用默认值,除非您需要将此标志也删除。
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;
}
268435456 - 完全控制 (0x10000000)
-536805376 - 修改,同步 (0xE0010000)
-1610612736 - 读取和执行,同步 (0xA0000000)
(为了节省您的计算)
FullControl
对应于 0x1F01FF,请查阅相关资料。然而,268435456 == 0x10000000 == GENERIC_ALL
是对第一个值的符号名称。意义是相同的,如果你将 GENERIC_ALL
通过 MapGenericMask
运行到文件中,你最终会得到 0x1F01FF,但它们仍然_不相同_。虽然这可能看起来像是吹毛求疵,但在安全方面,这些细节确实很重要。 - 0xC0000022L
GENERIC_ACCESS
设置错误,所以你的解决方法只能有限地发挥作用...显然,.NET Framework没有准备好创建可以在现实环境下完全运行的ACE(根据我的观察,这些ACE也可以被相应的类所读取)。 - 0xC0000022LGENERIC_ALL
(0x10000000)。也就是说,我看到过使用通用形式而不是具体形式的ACE的ACL。但是,FileSystemAccessRule
的(公共)构造函数会防止您使用枚举定义范围之外的任何内容 ☹ - 0xC0000022L