我有两个表,FileSystemRights
保存给定NTFS文件系统扫描的访问位掩码,FileSystemRights
================
Id Name Value
-- ---- -----
1 None 0
2 ListDirectory 1
3 ReadData 1
4 WriteData 2
5 CreateFiles 2
6 CreateDirectories 4
7 AppendData 4
8 ReadExtendedAttributes 8
9 WriteExtendedAttributes 16
10 ExecuteFile 32
11 Traverse 32
12 DeleteSubdirectoriesAndFiles 64
13 ReadAttributes 128
14 WriteAttributes 256
15 Write 278
16 Delete 65536
17 ReadPermissions 131072
18 Read 131209
19 ReadAndExecute 131241
20 Modify 197055
21 ChangePermissions 262144
22 TakeOwnership 524288
23 Synchronize 1048576
24 FullControl 2032127
25 GenericAll 268435456
26 GenericExecute 536870912
27 GenericWrite 1073741824
28 GenericRead 2147483648
Security
========
Id FileSystemRights IdentityReference
-- ---------------- -----------------
20 2032127 BUILTIN\Administrators
21 2032127 BUILTIN\Administrators
22 2032127 NT AUTHORITY\SYSTEM
23 268435456 CREATOR OWNER
24 1179817 BUILTIN\Users
25 4 BUILTIN\Users
26 2 BUILTIN\Users
MyView
======
SELECT s.Id AS SecurityId,
f.Name
FROM Security s
JOIN FileSystemRights f
ON CASE f.Value
WHEN 0 THEN s.FileSystemRights = f.Value
ELSE (s.FileSystemRights & f.Value) == f.Value
END
ORDER BY s.Id, f.Name;
等同于众所周知的位掩码的字符串表示。我需要创建一个视图,它暴露给定位掩码的预期(不仅仅是正确的)字符串表示。问题是几个枚举值复合并包含较低值的组合,因此理想的想法是不重复隐含值。
例如,值1179817(Security.Id = 24)应仅报告 ReadAndExecute 和 Synchronize ,不包括 ExecuteFile , ListDirectory ,读取, ReadAttributes , ReadData , ReadExtendedAttributes , ReadPermissions 和 Traverse ,因为它们都是 ReadAndExecute 的一部分(例如 ReadAndExecute & Read == 读取)。将它们全部展示显然是正确的,但用户只希望看到非隐式值。
我在SQL的限制范围内迷失了,以产生一个行为类似的联接,而没有一些糟糕的嵌套情况,这将是一个噩梦。
是否存在更好的编程方法?
const https = require('https');
const fs = require('fs');
var ssl = {
key: fs.readFileSync('/etc/letsencrypt/live/example.com/privkey.pem'),
cert: fs.readFileSync('/etc/letsencrypt/live/example.com/cert.pem')
};
var server = https.createServer(ssl, httpRequestsHandler).listen(_port_, function() {
process.setgid('www-data');
process.setuid('user1');
});
答案 0 :(得分:0)
将名称的实际值添加到查询中。 然后围绕它包装另一个查询,以过滤掉作为另一个值的子集的相同条目的值:
WITH AllValues(SecurityId, Name, Value) AS (
SELECT s.Id,
f.Name,
f.Value
FROM Security s
JOIN FileSystemRights f
ON CASE f.Value
WHEN 0 THEN s.FileSystemRights = f.Value
ELSE (s.FileSystemRights & f.Value) == f.Value
END
)
SELECT SecurityId,
Name
FROM AllValues
WHERE NOT EXISTS (SELECT *
FROM AllValues AS AV2
WHERE AV2.SecurityId = AllValues.SecurityId
AND (AV2.Value & AllValues.Value) != 0
AND AV2.Value > AllValues.Value
)
ORDER BY 1, 2;