Как вы программно определяете, является ли компьютер Windows членом домена?

Мне нужно определить, подключен ли компьютер к моей программе к любому домену. Неважно, в какой конкретной области он входит, просто связан ли он с чем-либо. Я кодирую vС++ против Win32 API.

Ответ 1

Прямо от Microsoft:

Как определить, является ли компьютер Windows NT/Windows 2000 членом домена

В этом подходе используется Windows API. Из резюме статьи:

В этой статье описывается, как определить, находится ли компьютер, под управлением Windows NT 4.0 или Windows 2000 является членом домена, является членом рабочей группы или является автономной компьютер с использованием локальной безопасности Авторизованные API.

В статье также приведен пример кода для небольшой программы, которая выводит, является ли компьютер, на котором запущена программа, частью домена, части рабочей группы или автономного компьютера.

Ответ 2

Я думаю, что функция NetServerEnum поможет вам в том, что вы хотите; Я бы попросил основные контроллеры домена с константой SV_TYPE_DOMAIN_CTRL для параметра servertype. Если вы его не получили, то вы не в домене.

Ответ 3

Вы можете проверить раздел реестра HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon для значения 'CachePrimaryDomain'.

Ответ 4

Код в примере MSDN немного устарел. Это функция, с которой я пришел, что работает.

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;
}

Ответ 5

Вот мертвый простой подход, о котором я не упоминал.

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
}

Это основано на идее, что если пользователь, который запускает этот код, в настоящее время не зарегистрирован в домене, тогда переменная среды USERDNSDOMAIN будет пустой или недоступной. Но есть некоторые оговорки, о которых вы должны подумать.

Плюсы:

  • Очень легко реализовать.
  • Надежность 99%.

Минусы:

  • Может завершиться неудачей или вернуть ложные результаты, если компьютер подключен к домену, но пользователь, выполняющий этот код, регистрируется на этом компьютере с локальной учетной записью.
  • Может произойти сбой или возврат ложных результатов, если компьютер подключен к домену, но сетевое подключение к контроллеру домена было недоступно во время входа/входа в систему с кэшированными учетными данными.

Ответ 6

как насчет имени компьютера?

edit: это был "ответ" с обратной стороны. То, что я имел в виду, это зашивание формы domain\name в имени компьютера. Это, конечно, означает, что вы знаете имя домена, оно не решает проблему просто знать, находится ли компьютер в любом домене.

Ответ 7

Избегайте LSA, который является неправильным методом. Вы должны использовать DS api (2 строки кода)