• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 748
  • Last Modified:

How to set a Component Services Application Identity / Credentials Programmatically

In component services, you can right click an application, click properties, and in the identity tab you can say "this user" and give domain\username and password.

Any ideas how to do this programmatically ?

I need it for a setup program

1 Solution
I'm not too familiar with COM+, but maybe http://www.codeproject.com/com/complus_admin.asp ("Programmatic administration of COM+ Applications with the COM+ Admin objects in VC++") can help.
To set the identity, access and launch permissions programmatically, you basically have to write the corresponding desired entries in the Registry yourself.

You need to build the desired security descriptor (have a look at SECURITY_DESCRIPTOR) in self-sufficient format (have a look at MakeSelfRelativeSD), then write it as a binary value under the server's AppID registry key (HKCR\AppID\{<AppID>} in these two entries (no prizes for figuring our which is which:-)

The RunAs entry (under the same key) controls the identity under which you want to run the server. It is specified as a string value in the format "domain\account\". It can also have ‘well known’ values (e.g. "InteractiveUser"). You can leave the <domain\> part out if you want to run the server under a local user account.

The password for the RunAs user account is stored in a secure area of the Registry (under the local security policy). Have a look at LsaStorePrivatedata. Here's an example (with no error checking):

memset(&objectAttributes, 0, sizeof (LSA_OBJECT_ATTRIBUTES));
objectAttributes.Length = sizeof(LSA_OBJECT_ATTRIBUTES);

HANDLE policyHandle = NULL;
LsaOpenPolicy(NULL, &objectAttributes, POLICY_CREATE_SECRET, &policyHandle);

WCHAR key[4 + GUIDSTR_MAX + 1];
wcscpy(key, L"SCM:");
wcscat(key, sAppID);  // sAppID is GUID string in Unicode

lsaKeyString.Buffer = key;
lsaKeyString.Length = (USHORT)((wcslen(key) + 1) * sizeof(WCHAR));
lsaKeyString.MaximumLength = (GUIDSTR_MAX + 5) * sizeof(WCHAR);

LSA_UNICODE_STRING lsaPasswordString;
lsaPasswordString.Buffer = password;  // password is plain text in Unicode
lsaPasswordString.Length = (USHORT) ((wcslen(password) + 1) * sizeof(WCHAR));
lsaPasswordString.MaximumLength = lsaPasswordString.Length;

LsaStorePrivateData(policyHandle, &lsaKeyString, &lsaPasswordString);

You have to make sure the corresponding user account has SeBatchLogonRight. Have a look at LookupAccountName and LsaAddAccountRights.

plqAuthor Commented:
Here's an easy vb6 way for the benefit of future readers

        Set obj = CreateObject("COMAdmin.COMAdminCatalog")
        Set objApps = obj.GetCollection("Applications")
        For lCount = 0 To objApps.Count - 1
            Set objProxy = objApps.Item(lCount)
            If objProxy.Name = "My Server Name" Then
                objProxy.Value("Identity") = sUserNameProxy
                objProxy.Value("Password") = sPasswordProxy
                objApps.SaveChanges 'lIndex
                Exit For
            End If
            Set objProxy = Nothing
        gsPasswordProxy = "x"
        Set objApps = Nothing
        Set obj = Nothing

Featured Post

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now