Мне нужно определить, подключен ли компьютер к моей программе к любому домену. Неважно, в какой конкретной области он входит, просто связан ли он с чем-либо. Я кодирую vС++ против Win32 API.
Как вы программно определяете, является ли компьютер Windows членом домена?
Ответ 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 строки кода)