|
|
//+--------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1996 - 1999
//
// File: dstest.cpp
//
// Contents: DS ping test
//
// History: 13-Mar-98 mattt created
//
//---------------------------------------------------------------------------
#include "pch.cpp"
#pragma hdrstop
#include <winldap.h>
#include <dsrole.h>
#include <dsgetdc.h>
#include <lmaccess.h>
#include <lmapibuf.h>
#include <cainfop.h>
#include "csldap.h"
#define __dwFILE__ __dwFILE_CERTCLIB_DSTEST_CPP__
#define DS_RETEST_SECONDS 3
HRESULT myDoesDSExist( IN BOOL fRetry) { HRESULT hr = S_OK;
static BOOL s_fKnowDSExists = FALSE; static HRESULT s_hrDSExists = HRESULT_FROM_WIN32(ERROR_NO_SUCH_DOMAIN); static FILETIME s_ftNextTest = {0,0}; if (s_fKnowDSExists && (s_hrDSExists != S_OK) && fRetry) // s_fKnowDSExists = FALSE; // force a retry
{ FILETIME ftCurrent; GetSystemTimeAsFileTime(&ftCurrent);
// if Compare is < 0 (next < current), force retest
if (0 > CompareFileTime(&s_ftNextTest, &ftCurrent)) s_fKnowDSExists = FALSE; }
if (!s_fKnowDSExists) { GetSystemTimeAsFileTime(&s_ftNextTest);
// set NEXT in 100ns increments
((LARGE_INTEGER *) &s_ftNextTest)->QuadPart += (__int64) (CVT_BASE * CVT_SECONDS * 60) * DS_RETEST_SECONDS;
// NetApi32 is delay loaded, so wrap to catch problems when it's not available
__try { DOMAIN_CONTROLLER_INFO *pDCI; DSROLE_PRIMARY_DOMAIN_INFO_BASIC *pDsRole; // ensure we're not standalone
pDsRole = NULL; hr = DsRoleGetPrimaryDomainInformation( // Delayload wrapped
NULL, DsRolePrimaryDomainInfoBasic, (BYTE **) &pDsRole);
_PrintIfError(hr, "DsRoleGetPrimaryDomainInformation"); if (S_OK == hr && (pDsRole->MachineRole == DsRole_RoleStandaloneServer || pDsRole->MachineRole == DsRole_RoleStandaloneWorkstation)) { hr = HRESULT_FROM_WIN32(ERROR_NO_SUCH_DOMAIN); _PrintError(hr, "DsRoleGetPrimaryDomainInformation(no domain)"); }
if (NULL != pDsRole) { DsRoleFreeMemory(pDsRole); // Delayload wrapped
} if (S_OK == hr) { // not standalone; return info on our DS
pDCI = NULL; hr = DsGetDcName( // Delayload wrapped
NULL, NULL, NULL, NULL, DS_DIRECTORY_SERVICE_PREFERRED, &pDCI); _PrintIfError(hr, "DsGetDcName"); if (S_OK == hr && 0 == (pDCI->Flags & DS_DS_FLAG)) { hr = HRESULT_FROM_WIN32(ERROR_CANT_ACCESS_DOMAIN_INFO); _PrintError(hr, "DsGetDcName(no domain info)"); } if (NULL != pDCI) { NetApiBufferFree(pDCI); // Delayload wrapped
} } s_fKnowDSExists = TRUE; } __except(hr = myHEXCEPTIONCODE(), EXCEPTION_EXECUTE_HANDLER) { }
// else just allow users without netapi flounder with timeouts
// if ds not available...
s_hrDSExists = myHError(hr); _PrintIfError2( s_hrDSExists, "DsRoleGetPrimaryDomainInformation/DsGetDcName", HRESULT_FROM_WIN32(ERROR_NETWORK_UNREACHABLE)); } return(s_hrDSExists); }
HRESULT myRobustLdapBind( OUT LDAP **ppldap, IN BOOL fGC) { return(myRobustLdapBindEx(fGC, FALSE, LDAP_VERSION2, NULL, ppldap, NULL)); }
HRESULT myRobustLdapBindEx( IN BOOL fGC, IN BOOL fRediscover, IN ULONG uVersion, OPTIONAL IN WCHAR const *pwszDomainName, OUT LDAP **ppldap, OPTIONAL OUT WCHAR **ppwszForestDNSName) { HRESULT hr; ULONG ldaperr; DWORD GetDSNameFlags; LDAP *pld = NULL;
GetDSNameFlags = DS_RETURN_DNS_NAME; if (fGC) { GetDSNameFlags |= DS_GC_SERVER_REQUIRED; }
// bind to ds
while (TRUE) { if (NULL != pld) { ldap_unbind(pld); }
pld = ldap_init( const_cast<WCHAR *>(pwszDomainName), fGC? LDAP_GC_PORT : LDAP_PORT); if (NULL == pld) { hr = myHLdapLastError(NULL, NULL); if (!fRediscover) { _PrintError2(hr, "ldap_init", hr); fRediscover = TRUE; continue; } _JumpError(hr, error, "ldap_init"); }
if (fRediscover) { GetDSNameFlags |= DS_FORCE_REDISCOVERY; } ldaperr = ldap_set_option( pld, LDAP_OPT_GETDSNAME_FLAGS, (VOID *) &GetDSNameFlags); if (LDAP_SUCCESS != ldaperr) { hr = myHLdapError(pld, ldaperr, NULL); if (!fRediscover) { _PrintError2(hr, "ldap_set_option", hr); fRediscover = TRUE; continue; } _JumpError(hr, error, "ldap_set_option"); }
// do not want this to turn on if uVersion is not LDAP_VERSION2
//if (LDAP_VERSION2 == uVersion)
if (IsWhistler()) { ldaperr = ldap_set_option(pld, LDAP_OPT_SIGN, LDAP_OPT_ON); if (LDAP_SUCCESS != ldaperr) { hr = myHLdapError2(pld, ldaperr, LDAP_PARAM_ERROR, NULL); if (!fRediscover) { _PrintError2(hr, "ldap_set_option", hr); fRediscover = TRUE; continue; } _JumpError(hr, error, "ldap_set_option"); } }
// set the client version. No need to set LDAP_VERSION2 since
// this is the default
if (LDAP_VERSION2 != uVersion) { ldaperr = ldap_set_option(pld, LDAP_OPT_VERSION, &uVersion); if (LDAP_SUCCESS != ldaperr) { hr = myHLdapError(pld, ldaperr, NULL); if (!fRediscover) { _PrintError2(hr, "ldap_set_option", hr); fRediscover = TRUE; continue; } _JumpError(hr, error, "ldap_set_option"); } }
ldaperr = ldap_bind_s(pld, NULL, NULL, LDAP_AUTH_NEGOTIATE); if (LDAP_SUCCESS != ldaperr) { hr = myHLdapError(pld, ldaperr, NULL); if (!fRediscover) { _PrintError2(hr, "ldap_bind_s", hr); fRediscover = TRUE; continue; } _JumpError(hr, error, "ldap_bind_s"); }
if (NULL != ppwszForestDNSName) { WCHAR *pwszDomainControllerName;
hr = myLdapGetDSHostName(pld, &pwszDomainControllerName); if (S_OK != hr) { if (!fRediscover) { _PrintError2(hr, "myLdapGetDSHostName", hr); fRediscover = TRUE; continue; } _JumpError(hr, error, "myLdapGetDSHostName"); } hr = myDupString(pwszDomainControllerName, ppwszForestDNSName); _JumpIfError(hr, error, "myDupString"); } break; } *ppldap = pld; pld = NULL; hr = S_OK;
error: if (NULL != pld) { ldap_unbind(pld); } return(hr); }
|