【问题标题】:How can I change COM Security settings programmatically by c#?如何通过 c# 以编程方式更改 COM 安全设置?
【发布时间】:2015-07-30 09:20:05
【问题描述】:

我需要使用 .NET 方法以编程方式更改 COM 安全权限。 我的意思是这些设置:

我该怎么做?谢谢!

【问题讨论】:

    标签: c# .net


    【解决方案1】:

    据我所知,没有 API 可以做到这一点。不过COM和DCOM的访问控制都是在注册表中设置的,主要是在“隐身”OLE下(由于历史原因)。同时 .NET 有标准的类来操作注册表。

    所以这是我在面对这个任务时应该做的:

    • 启动注册表监视器,例如 Mark Russinovich 的 formerly SysInternals, now Microsoft

    • 使用 Windows UI 以交互方式设置一些 COM 设置,并监控注册表更改。

    • 可选但强烈推荐:在有一些非常有针对性的搜索关键字( 注册表项)尝试在 google 中获取文档/代码,或者更好的方法 在github中搜索代码

    • 实现我的 C# 类,什么在操作适当的 注册表类

    【讨论】:

    【解决方案2】:

    我知道这个热带很旧,但这是我最终使用的解决方案,以防有人需要它。如上所述,我找不到任何 API 来执行此操作,必须直接在存储坐席的注册表项上工作。 应编辑填充键:

    • HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Ole\DefaultAccessPermission
    • HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Ole\DefaultLaunchPermission

    权限以二进制形式存储。 你可以试试我的代码:

    static class ComACLRights
    {
        public const int COM_RIGHTS_EXECUTE = 1;
        public const int COM_RIGHTS_EXECUTE_LOCAL = 2;
        public const int COM_RIGHTS_EXECUTE_REMOTE = 4;
        public const int COM_RIGHTS_ACTIVATE_LOCAL = 8;
        public const int COM_RIGHTS_ACTIVATE_REMOTE = 16;
    }
    
    static void Main(string[] args)
    {
         SetCOMSercurityAccess("testuser", "DefaultAccessPermission");
         SetCOMSercurityAccess("testuser", "DefaultLaunchPermission");
    }
    
    private static void SetCOMSercurityAccess(string username, string regKey)
    {
        //Get sid from username
        NTAccount f = new NTAccount(username);
        SecurityIdentifier sid = (SecurityIdentifier)f.Translate(typeof(SecurityIdentifier));
    
        //Read reg key responsible for COM Sercurity
        var accessKey = Registry.GetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Ole", regKey, null);
    
        RawSecurityDescriptor sd;
    
        if (accessKey == null)
        {
            //Key does not exist
            sd = new RawSecurityDescriptor("");
        }
        else
        {
            //read security settings
            sd = new RawSecurityDescriptor(accessKey as byte[], 0);
        }
    
        //Look fo input foruser
        var acl = sd.DiscretionaryAcl;
        var found = false;
        foreach (CommonAce ca in acl)
        {
            if (ca.SecurityIdentifier == sid)
            {
                //ensure local access is set
                ca.AccessMask |= ComACLRights.COM_RIGHTS_EXECUTE | ComACLRights.COM_RIGHTS_EXECUTE_LOCAL | ComACLRights.COM_RIGHTS_ACTIVATE_LOCAL;    //set local access.  Always set execute
                found = true;
                break;
            }
        }
        if (!found)
        {
            CommonAce ca = new CommonAce(
                AceFlags.None,
                AceQualifier.AccessAllowed,
                ComACLRights.COM_RIGHTS_EXECUTE | ComACLRights.COM_RIGHTS_EXECUTE_LOCAL | ComACLRights.COM_RIGHTS_ACTIVATE_LOCAL,
                    sid,
                    false,
                    null);
            acl.InsertAce(acl.Count, ca);
        }
        //re-set the ACL
        sd.DiscretionaryAcl = acl;
    
        //Convert back to binary and save
        byte[] binaryform = new byte[sd.BinaryLength];
        sd.GetBinaryForm(binaryform, 0);
        Registry.SetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Ole", regKey, binaryform, RegistryValueKind.Binary);
    }
    

    这段代码的灵感主要来自this answer

    【讨论】:

      猜你喜欢
      • 2012-06-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-09
      • 1970-01-01
      • 1970-01-01
      • 2011-12-12
      • 2010-12-06
      相关资源
      最近更新 更多