2

我正在尝试将访问规则添加到RegistryKey这样的:

using ( RegistryKey registry = OpenOrCreateMyKey() )
{
    RegistrySecurity security = registry.GetAccessControl();
    security.AddAccessRule( new RegistryAccessRule(
        new SecurityIdentifier( WellKnownSidType.BuiltinUsersSid, null ),
        RegistryRights.WriteKey,
        InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit,
        PropagationFlags.None,
        AccessControlType.Allow ) );
    registry.SetAccessControl( security );
}

但是,如果注册表被破坏,则会AddAccessRule引发异常(Reflector 显示该GetAccessControl调用预先确定它们不是规范的,并且当您在RegistrySecurity实例处于该状态时尝试执行写入时,您会触发故障安全):

System.InvalidOperationException: This access control list is not in canonical form and therefore cannot be modified.

运行regedt32(可能还有regedit)然后显示一个弹出窗口the permissions on <key> are incorrectly ordered, which may cause some entries to be ineffective <paraphrasing>Do you want to unmangle them now? Y/N</paraprasing>

我在这个问题上看到的最权威的文章是http://www.codeproject.com/KB/system/accessctrl3.aspx,它说:

但是,控制标志是作为属性实现的(谈论不一致!)。AreAccessRulesProtected您可以从/检索自动继承设置AreAuditRulesProtected(回想一下,如果 ACL 受保护,它不会自动继承)。如果您阅读第 2 部分,您会知道某些 Windows API 不支持继承,因此可能会破坏您机器的继承设置。好消息是 .NET 完全支持继承机制并将正确保留继承设置。如果您打开的安全描述符以某种方式获得了混乱的 ACL(可能来自某些流氓 Win32 应用程序),如果您尝试对其进行编辑,则会引发 InvalidOperationException。

通常,此类非规范 ACL 是使用 [sinceretired] NewSID 工具产生的,人们写知识库文章说“那就别再那样做了”

但是,至关重要的是,这并不总是原因,有时代码只需要工作。有什么好的干净安全的方法来处理这个?

我将提供两个答案,人们可​​以投票和挑选漏洞、投票、评论和挑剔。

4

2 回答 2

2

方法1是忽略继承的权限并盲目地写你想要的东西: -

using ( RegistryKey registry = OpenOrCreateMyKey() )
{
    RegistrySecurity security = new RegistrySecurity();
    security.AddAccessRule( new RegistryAccessRule( ... ));
    registry.SetAccessControl( security );
}

问题是,我不知道潜在的负面影响是什么。我很高兴所有需要访问的人都能从我的规则中获得它。但是,它与操作系统基础架构的其余部分配合得很好吗?

于 2010-02-10T12:36:15.063 回答
1

方法2是尝试第一种方式,只有在必要时才回退到肮脏的方式:-

using ( RegistryKey registry = OpenOrCreateMyKey() )
{
    RegistrySecurity security = new RegistrySecurity();
    if ( !security.AreAccessRulesCanonical )
    {
        Log.WriteWarning( "Registry permissions (likely ones inherited from parent) are inconsistent (RegistrySecurity.AreAccessRulesCanonical is false), so using alternate permissioning algorithm, Has NewSID or another tool mangled permissions? regedt32 can be used to analyze the issue." );
         // Ignore parent ACLs and just blindly stuff in this ACL (which will continue to be inherited)
         security = new RegistrySecurity();
     }

    security.AddAccessRule( new RegistryAccessRule( ... ));
    registry.SetAccessControl( security );
}

除了方法 1中的弱点之外,这还具有不可预测的行为,但至少它在一定程度上与原始方法兼容。

于 2010-02-10T12:40:40.187 回答