How to change DCOM config identity programmatically

6.3k views Asked by At

Is there any way to get the information about Launching identity of DCOM application programmatically. See the picture attached to understand what i mean.

Screenshot with application properties from DCOM Config

I tried to use WMI

ManagementObjectSearcher s = new ManagementObjectSearcher(new ManagementScope(@"\\.\root\cimv2"), new ObjectQuery(
                "select * from Win32_DCOMApplicationSetting  where AppID='{048EB43E-2059-422F-95E0-557DA96038AF}'"))
ManagementObjectCollection dcomSett = s.Get();
var value = dcomSett.Cast<ManagementObject>().ToArray()
             [0].Properties["RunAsUser"].Value;

but "RunAsUser" property was empty. Also tried Interop.COMAdmin

COMAdmin.COMAdminCatalogClass catalog = (COMAdmin.COMAdminCatalogClass)new COMAdmin.COMAdminCatalog();
(COMAdmin.COMAdminCatalogCollection)catalog.GetCollection("Applications")

in this way i managed to get applications which are listed under the "COM+ Applications" node in the "Component Services" snap-in of MMC:

COM+ applications

I'm new in COM, DCOM, COM+ stuff and sure that i missed something important.

After a while i found out why i used to get NULL in the first approach (ManagementObject). You will receive:

  • NULL if identity is currently set to The launching user
  • "Interactive User" in case of "The interactive user"
  • some string with username in case of third option (see the first picture)

But still i need a way to change identity for items like Microsoft PowerPoint Slide under DCOM Config node in MMC.

4

There are 4 answers

1
Ron Hagerman On

This works for me on my development server. Keep in mind, it is run against the server directly on the server

using COMAdmin;
using System;

namespace ComComponents
{
    class Program
    {
        static void Main(string[] args)
        {
            COMAdminCatalog catalog = new COMAdminCatalog();
            COMAdminCatalogCollection applications = catalog.GetCollection("Applications");

            applications.Populate();

            for (int i = 0; i < applications.Count; i++)
            {
                COMAdminCatalogObject application = applications.Item[i];

                Console.WriteLine(application.Name);
                Console.WriteLine(application.Value["Identity"]);
            }

            Console.WriteLine("Press any key to continue...");
            Console.ReadKey();
        }
    }
}
2
Manuel Quijada On

I am using COMAdmin DLL successfully. Try something like this:

COMAdminCatalog catalog = new COMAdminCatalog();
COMAdminCatalogCollection applications = catalog.GetCollection("Applications");

applications.Populate();

for (int i = 0; i < applications.Count; i++)
{
    COMAdminCatalogObject application = COMAppCollectionInUse.Item[i];
    if (application.Name == "Your COM+ application name")
    {
            application.Value["Identity"] = "nt authority\\localservice"; // for example
    }
}
0
M. Jamil Raza On

This is very simple , you can get APPId from

Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Classes\AppID\{048EB43E-2059-422F-95E0-557DA96038AF}

using

(RegistryKey dcomPPTIdentity = Registry.LocalMachine.OpenSubKey("Software\\Classes\\AppID\\{048EB43E-2059-422F-95E0-557DA96038AF}"))
{
    if (dcomPPTIdentity != null)
    {
         Registry.SetValue(dcomPPTIdentity.ToString(), "RunAs", "userName");
    }
}
0
Brad Albright On

In the DCOM config, if you are using a specific user for the identity and you want to update the password via code, you need to update it in the Local Security Authority (LSA). This is possible with Windows API calls. MS has some sample code for a utility called dcomperm that does it, and you can see how they implemented in C++. You could make the same calls in C#. See the SetRunAsPassword method here. They are using the method LsaOpenPolicy to get a handle to the policy and calling LsaStorePrivateData to update the password. Then they are adding "login as a batch job" access to the account (but that shouldn't be necessary if you are only changing the password).

This sample code on pinvoke.net looks like it is making the requisite calls, except for the optional part about granting the login as a batch job permission. Note the "key" in the LSA is in the format SCM:{GUID-of-DCOM-object} Example: SCM:{00000000-0000-0000-0000-000000000000}

Oh, and I should mention as an aside that if you wanted to change the RunAs user itself (i.e. the username), you'd need to also update that in the windows registry directly (AFAIK that's the only way to do it). DCOM entries are stored under HKLM\SOFTWARE\Classes\AppID. You can do that with WMI or just use the Registry classes in .NET.