Question

I need a way to determine whether the computer running my program is joined to any domain. It doesn't matter what specific domain it is part of, just whether it is connected to anything. I'm coding in vc++ against the Win32 API.

Was it helpful?

Solution

Straight from Microsoft:

How To Determine If a Windows NT/Windows 2000 Computer Is a Domain Member

This approach uses the Windows API. From the article summary:

This article describes how to determine if a computer that is running Windows NT 4.0 or Windows 2000 is a member of a domain, is a member of a workgroup, or is a stand-alone computer using the Local Security Authority APIs.

The article also provides sample code for a small program that outputs whether the computer the program is running on is part of a domain, part of a workgroup, or a standalone computer.

OTHER TIPS

I think the NetServerEnum function will help you in what you want; I would ask for the primary domain controllers with the SV_TYPE_DOMAIN_CTRL constant for servertype parameter. If you don't get any, then you're not in a domain.

You can check the registry key HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon for the value of 'CachePrimaryDomain'.

The code in the MSDN sample is a little outdated. This is the function I came up with that works.

bool ComputerBelongsToDomain()
{
    bool ret = false;

    LSA_OBJECT_ATTRIBUTES objectAttributes;
    LSA_HANDLE policyHandle;
    NTSTATUS status;
    PPOLICY_PRIMARY_DOMAIN_INFO info;

    // Object attributes are reserved, so initialize to zeros.
    ZeroMemory(&objectAttributes, sizeof(objectAttributes));

    status = LsaOpenPolicy(NULL, &objectAttributes, GENERIC_READ | POLICY_VIEW_LOCAL_INFORMATION, &policyHandle);
    if (!status)
    {
        status = LsaQueryInformationPolicy(policyHandle, PolicyPrimaryDomainInformation, (LPVOID*)&info);
        if (!status)
        {
            if (info->Sid)
                ret = true;

            LsaFreeMemory(info);
        }

        LsaClose(policyHandle);
    }

    return ret;
}

Here is a dead simple approach I don't see mentioned.

TCHAR UserDnsDomain[128] = { 0 }; 
DWORD Result = 0;

Result = GetEnvironmentVariable("USERDNSDOMAIN", UserDnsDomain, sizeof(UserDnsDomain));

if (Result == 0 || Result >= sizeof(UserDnsDomain) || GetLastError() == ERROR_ENVVAR_NOT_FOUND)
{
    return(FALSE); // Not logged in to a domain
}

This is predicated on the idea that if the user who is running this code is not currently logged in to a domain, then the USERDNSDOMAIN environment variable will be empty or unavailable. But there are some caveats you should think about.

Pros:

  • Very easy to implement.
  • 99% reliable.

Cons:

  • May fail or return false results if the computer is domain joined, but the user executing this code is logged on to that computer with a local account.
  • May fail or return false results if the computer is domain joined, but network connectivity to a domain controller was unavailable at the time of logon/user logged on with cached credentials.

Avoid LSA which is a wrong method. You must use DS api (2 lines of code)

what about from the name of the computer?

edit: this was a crapy 'answer' from way back. What I meant was cheching for the form domain\name in the computer name. That of course implies that you do know the name of the domain, it does not solves the issue of just knowing if the computer is in any domain.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top