当前位置:  开发笔记 > 编程语言 > 正文

dcomcnfg以编程方式运行

如何解决《dcomcnfg以编程方式运行》经验,为你挑选了2个好方法。

我可以找到各种关于如何为DCOM编程的东西,但实际上没有关于如何以编程方式设置/检查安全性的内容.

我不是要重新创建dcomcnfg,但如果我知道如何在C#(首选或VB.net)中重现dcomcnfg的所有功能,那么我的目标就在眼前.

我似乎无法在此找到任何好的资源,没有开源API或甚至是如何执行每个步骤的快速示例.即使在这里,DCOM或dcomcnfg也没有返回任何结果,也没有关于如何设置/验证/列出安全性的结果.

如果有人对开放API或某些示例有一些指示,我将不胜感激.



1> longofest..:

丹尼尔发布的答案很有帮助.谢谢你,丹尼尔!

Microsoft文档的一个问题是它们表明注册表值包含二进制形式的ACL.所以,举例来说,如果你试图设置机器的默认访问(而不是每个进程),你会被访问的注册表项HKEY_LOCAL_MACHINE\SOFTWARE \微软\的Ole\DefaultAccessPermission.但是,在我最初尝试使用System.Security.AccessControl.RawACL类访问此密钥失败.

由于Daniel的代码表明该值实际上不是ACL,但实际上是一个带有ACL的SecurityDescriptor.

所以,即使我知道这篇文章已经过时了,我也会发布我的解决方案来检查和设置安全设置,并添加NetworkService以进行默认本地访问.当然,你可以采取这种方式并使其更好我确定,但要开始,你只需要更改密钥和访问掩码.

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;
}
class Program
{
    static void Main(string[] args)
    {
        var value = Registry.GetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Ole", "DefaultAccessPermission", null);

        RawSecurityDescriptor sd;
        RawAcl acl;

        if (value == null)
        {
            System.Console.WriteLine("Default Access Permission key has not been created yet");
            sd = new RawSecurityDescriptor("");
        }else{
            sd = new RawSecurityDescriptor(value as byte[], 0);
        }
        acl = sd.DiscretionaryAcl;
        bool found = false;
        foreach (CommonAce ca in acl)
        {
            if (ca.SecurityIdentifier.IsWellKnown(WellKnownSidType.NetworkServiceSid))
            {
                //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){
            //Network Service was not found.  Add it to the ACL
            SecurityIdentifier si = new SecurityIdentifier( 
                WellKnownSidType.NetworkServiceSid, null);
            CommonAce ca = new CommonAce(
                AceFlags.None, 
                AceQualifier.AccessAllowed, 
                ComACLRights.COM_RIGHTS_EXECUTE | ComACLRights.COM_RIGHTS_EXECUTE_LOCAL | ComACLRights.COM_RIGHTS_ACTIVATE_LOCAL, 
                si, 
                false, 
                null);
            acl.InsertAce(acl.Count, ca);
        }
        //re-set the ACL
        sd.DiscretionaryAcl = acl;

        byte[] binaryform = new byte[sd.BinaryLength];
        sd.GetBinaryForm(binaryform, 0);
        Registry.SetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Ole", "DefaultAccessPermission", binaryform, RegistryValueKind.Binary);
    }
}



2> Daniel Bruce..:

面对类似的情况(配置从MSI DCOM安全),我成功地创建一个解决方案,做什么,我想在HKEY_CLASSES_ROOT \的AppID更改注册表键值{APP-GUID-GOES-HERE}.感谢Arnout的回答,让我走上了正确的道路.

具体来说,我创建了一种方法来编辑DCOM对象的安全权限,这些权限存储在LaunchPermission和AccessPermission注册表项值中.这些是序列化的安全描述符,您可以通过传递二进制数据来访问它们RawSecurityDescriptor.这个类简化了很多的美味.NET-Y时尚的细节,但你还是要顾及所有有关的Windows ACL的逻辑细节,你必须确保通过编写安全描述符回注册表 RawSecurityDescriptor.GetBinaryForm.

我创建的方法被调用EditOrCreateACE.此方法将编辑帐户的现有ACE,或插入新帐户,并确保访问掩码已设置传递的标志.我在这里附上它作为一个例子,这绝不是如何处理它的任何权威,因为我对Windows ACL的东西知之甚少:

// These are constants for the access mask on LaunchPermission.
// I'm unsure of the exact constants for AccessPermission
private const int COM_RIGHTS_EXECUTE = 1;
private const int COM_RIGHTS_EXECUTE_LOCAL = 2;
private const int COM_RIGHTS_EXECUTE_REMOTE = 4;
private const int COM_RIGHTS_ACTIVATE_LOCAL = 8;
private const int COM_RIGHTS_ACTIVATE_REMOTE = 16;

void EditOrCreateACE(string keyname, string valuename,
                      string accountname, int mask)
{
    // Get security descriptor from registry
    byte[] keyval = (byte[]) Registry.GetValue(keyname, valuename,
                                               new byte[] { });
    RawSecurityDescriptor sd;
    if (keyval.Length > 0) {
        sd = new RawSecurityDescriptor(keyval, 0);
    } else {
        sd = InitializeEmptySecurityDescriptor();
    }
    RawAcl acl = sd.DiscretionaryAcl;

    CommonAce accountACE = null;

    // Look for the account in the ACL
    int i = 0;
    foreach (GenericAce ace in acl) {
        if (ace.AceType == AceType.AccessAllowed) {
            CommonAce c_ace = ace as CommonAce;
            NTAccount account = 
                c_ace.SecurityIdentifier.Translate(typeof(NTAccount))
                as NTAccount;
            if (account.Value.Contains(accountname)) {
                accountACE = c_ace;
            }
            i++;
        }
    }

    // If no ACE found for the given account, insert a new one at the end
    // of the ACL, otherwise just set the mask
    if (accountACE == null) {
        SecurityIdentifier ns_account = 
            (new NTAccount(accountname)).Translate(typeof(SecurityIdentifier))
            as SecurityIdentifier;
        CommonAce ns = new CommonAce(AceFlags.None, AceQualifier.AccessAllowed,
                                     mask, ns_account, false, null);
        acl.InsertAce(acl.Count, ns);
    } else {
        accountACE.AccessMask |= mask;
    }

    // Write security descriptor back to registry
    byte[] binarySd = new byte[sd.BinaryLength];
    sd.GetBinaryForm(binarySd, 0);
    Registry.SetValue(keyname, valuename, binarySd);
}

private static RawSecurityDescriptor InitializeEmptySecurityDescriptor()
{
    var localSystem = 
        new SecurityIdentifier(WellKnownSidType.LocalSystemSid, null);
    var new_sd =
        new RawSecurityDescriptor(ControlFlags.DiscretionaryAclPresent,
                                  localSystem, localSystem, null,
                                  new RawAcl(GenericAcl.AclRevision, 1));
    return new_sd;
}

请注意,此代码绝不是完美的.如果注册表中缺少这些ACL的整个注册表项值,则合成的ACL将仅授予对已通过帐户的访问权限,而不允许其他任何内容.我也确定有很多错误情况,我没有正确处理,细节我已经掩盖了.同样,它是如何在.NET中处理DCOM ACL 的一个示例.

推荐阅读
罗文彬2502852027
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有