mirror of https://github.com/tongzx/nt5src
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
585 lines
19 KiB
585 lines
19 KiB
//++
|
|
//
|
|
// Copyright (C) Microsoft Corporation, 1987 - 1999
|
|
//
|
|
// Module Name:
|
|
//
|
|
// member.c
|
|
//
|
|
// Abstract:
|
|
//
|
|
// Queries into network drivers
|
|
//
|
|
// Author:
|
|
//
|
|
// Anilth - 4-20-1998
|
|
//
|
|
// Environment:
|
|
//
|
|
// User mode only.
|
|
// Contains NT-specific code.
|
|
//
|
|
// Revision History:
|
|
//
|
|
//--
|
|
|
|
|
|
#include "precomp.h"
|
|
#undef IsEqualGUID
|
|
#include "objbase.h"
|
|
#include "regutil.h"
|
|
#include "strings.h"
|
|
|
|
const WCHAR c_wszUserDnsDomain[] = L"USERDNSDOMAIN";
|
|
|
|
BOOL IsSysVolReady(NETDIAG_PARAMS* pParams);
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
MemberTest
|
|
|
|
Determine the machines role and membership.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
TRUE: Test suceeded.
|
|
FALSE: Test failed
|
|
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT MemberTest(NETDIAG_PARAMS* pParams, NETDIAG_RESULT* pResults)
|
|
{
|
|
PDSROLE_PRIMARY_DOMAIN_INFO_BASIC pPrimaryDomain = NULL;
|
|
DWORD dwErr;
|
|
NTSTATUS Status;
|
|
DWORD LogonServerLength;
|
|
WCHAR swzLogonServer[MAX_PATH+1];
|
|
int iBuildNo;
|
|
BOOL fDomain; // TRUE if domain, FALSE is workgroup
|
|
|
|
LSA_HANDLE PolicyHandle = NULL;
|
|
PPOLICY_DNS_DOMAIN_INFO pPolicyDomainInfo = NULL;
|
|
OBJECT_ATTRIBUTES ObjAttributes;
|
|
|
|
PrintStatusMessage(pParams,0, IDS_MEMBER_STATUS_MSG);
|
|
|
|
//
|
|
// Get the build number of this machine
|
|
//
|
|
if (pResults->Global.pszCurrentBuildNumber &&
|
|
(pResults->Global.pszCurrentBuildNumber[0] == 0))
|
|
{
|
|
PrintStatusMessage(pParams,0, IDS_GLOBAL_FAIL_NL);
|
|
PrintStatusMessage(pParams,0, IDS_MEMBER_CANNOT_DETERMINE_BUILD);
|
|
pResults->Global.hrMemberTestResult = E_FAIL;
|
|
return E_FAIL;
|
|
}
|
|
|
|
iBuildNo = _ttoi( pResults->Global.pszCurrentBuildNumber );
|
|
|
|
|
|
// Assmume that the test has succeeded
|
|
pResults->Global.hrMemberTestResult = hrOK;
|
|
|
|
|
|
//
|
|
// Get the name of the domain this machine is a member of
|
|
//
|
|
|
|
dwErr = DsRoleGetPrimaryDomainInformation(
|
|
NULL, // local call
|
|
DsRolePrimaryDomainInfoBasic,
|
|
(PBYTE *) &pPrimaryDomain);
|
|
pResults->Global.pPrimaryDomainInfo = pPrimaryDomain;
|
|
if (dwErr != NO_ERROR)
|
|
{
|
|
PrintStatusMessage(pParams,0, IDS_GLOBAL_FAIL_NL);
|
|
PrintStatusMessage(pParams,0, IDS_MEMBER_CANNOT_DETERMINE_DOMAIN);
|
|
pResults->Global.hrMemberTestResult = E_FAIL;
|
|
goto Cleanup;
|
|
}
|
|
|
|
//
|
|
// Handle being a member of a domain
|
|
//
|
|
if ( pPrimaryDomain->MachineRole != DsRole_RoleStandaloneWorkstation &&
|
|
pPrimaryDomain->MachineRole != DsRole_RoleStandaloneServer )
|
|
{
|
|
//
|
|
// Ensure the netlogon service is running.
|
|
//
|
|
|
|
dwErr = IsServiceStarted( _T("Netlogon") );
|
|
|
|
if ( dwErr != NO_ERROR )
|
|
{
|
|
PrintStatusMessage(pParams,0, IDS_GLOBAL_FAIL_NL);
|
|
PrintStatusMessage(pParams,0, IDS_MEMBER_NETLOGON_NOT_RUNNING);
|
|
}
|
|
else
|
|
{
|
|
pResults->Global.fNetlogonIsRunning = TRUE;
|
|
}
|
|
|
|
//
|
|
// Save the name of this domain as a domain to test.
|
|
// Do NOT free this up. This will get freed up
|
|
// by the code that frees up the list of domains.
|
|
|
|
pResults->Global.pMemberDomain = AddTestedDomain( pParams,
|
|
pResults,
|
|
pPrimaryDomain->DomainNameFlat,
|
|
pPrimaryDomain->DomainNameDns,
|
|
TRUE );
|
|
if (pResults->Global.pMemberDomain == NULL)
|
|
{
|
|
PrintStatusMessage(pParams,0, IDS_GLOBAL_FAIL_NL);
|
|
pResults->Global.hrMemberTestResult = S_FALSE;
|
|
goto Cleanup;
|
|
}
|
|
|
|
|
|
|
|
//
|
|
// Get the SID of the domain we're a member of
|
|
//
|
|
|
|
InitializeObjectAttributes(
|
|
&ObjAttributes,
|
|
NULL,
|
|
0L,
|
|
NULL,
|
|
NULL
|
|
);
|
|
|
|
Status = LsaOpenPolicy(
|
|
NULL,
|
|
&ObjAttributes,
|
|
POLICY_VIEW_LOCAL_INFORMATION,
|
|
&PolicyHandle );
|
|
|
|
if (! NT_SUCCESS(Status))
|
|
{
|
|
PrintStatusMessage(pParams,0, IDS_GLOBAL_FAIL_NL);
|
|
PrintDebugSz(pParams, 0, _T(" [FATAL] Member: Cannot LsaOpenPolicy."));
|
|
pResults->Global.hrMemberTestResult = S_FALSE;
|
|
goto Cleanup;
|
|
}
|
|
|
|
Status = LsaQueryInformationPolicy(
|
|
PolicyHandle,
|
|
PolicyDnsDomainInformation,
|
|
(PVOID *) &pPolicyDomainInfo
|
|
);
|
|
|
|
if (! NT_SUCCESS(Status))
|
|
{
|
|
PrintStatusMessage(pParams,0, IDS_GLOBAL_FAIL_NL);
|
|
if (pParams->fDebugVerbose)
|
|
PrintDebugSz(pParams, 0, _T(" [FATAL] Member: Cannot LsaQueryInformationPolicy (PolicyDnsDomainInformation).") );
|
|
pResults->Global.hrMemberTestResult = S_FALSE;
|
|
goto Cleanup;
|
|
}
|
|
|
|
if ( pPolicyDomainInfo->Sid == NULL )
|
|
{
|
|
PrintStatusMessage(pParams,0, IDS_GLOBAL_FAIL_NL);
|
|
|
|
// IDS_MEMBER_11206 " [FATAL] Member: Cannot LsaQueryInformationPolicy has no domain sid."
|
|
PrintDebug(pParams, 0, IDS_MEMBER_11206 );
|
|
pResults->Global.hrMemberTestResult = S_FALSE;
|
|
goto Cleanup;
|
|
}
|
|
|
|
//
|
|
// Save the domain sid for other tests
|
|
//
|
|
pResults->Global.pMemberDomain->DomainSid =
|
|
Malloc(RtlLengthSid(pPolicyDomainInfo->Sid));
|
|
if (pResults->Global.pMemberDomain->DomainSid == NULL)
|
|
{
|
|
PrintStatusMessage(pParams,0, IDS_GLOBAL_FAIL_NL);
|
|
// IDS_MEMBER_11207 " Member: Out of memory\n"
|
|
PrintDebug(pParams, 0, IDS_MEMBER_11207);
|
|
pResults->Global.hrMemberTestResult = S_FALSE;
|
|
goto Cleanup;
|
|
}
|
|
|
|
RtlCopyMemory( pResults->Global.pMemberDomain->DomainSid,
|
|
pPolicyDomainInfo->Sid,
|
|
RtlLengthSid( pPolicyDomainInfo->Sid ) );
|
|
}
|
|
|
|
//Bug 293635, check whether system volume is ready if the machine is a DC
|
|
if (DsRole_RoleBackupDomainController == pPrimaryDomain->MachineRole ||
|
|
DsRole_RolePrimaryDomainController == pPrimaryDomain->MachineRole)
|
|
{
|
|
pResults->Global.fSysVolNotReady = !IsSysVolReady(pParams);
|
|
if (pResults->Global.fSysVolNotReady)
|
|
pResults->Global.hrMemberTestResult = S_FALSE;
|
|
}
|
|
|
|
|
|
//
|
|
// Get the name of the logged on user.
|
|
//
|
|
Status = LsaGetUserName( &pResults->Global.pLogonUser,
|
|
&pResults->Global.pLogonDomainName );
|
|
|
|
if ( !NT_SUCCESS(Status))
|
|
{
|
|
PrintStatusMessage(pParams,0, IDS_GLOBAL_FAIL_NL);
|
|
PrintStatusMessage(pParams,0, IDS_MEMBER_UNKNOWN_LOGON);
|
|
pResults->Global.hrMemberTestResult = S_FALSE;
|
|
goto Cleanup;
|
|
}
|
|
|
|
|
|
//
|
|
// If we're not logged onto a local account,
|
|
// add the logon domain to the list of tested domains
|
|
//
|
|
|
|
if ( _wcsicmp( pResults->Global.swzNetBiosName,
|
|
pResults->Global.pLogonDomainName->Buffer ) != 0 )
|
|
{
|
|
LPWSTR pwszLogonDomainDnsName = NULL;
|
|
DWORD cchLogonDomainDnsName = 0;
|
|
|
|
cchLogonDomainDnsName = GetEnvironmentVariableW(c_wszUserDnsDomain,
|
|
NULL,
|
|
0);
|
|
|
|
if (cchLogonDomainDnsName)
|
|
{
|
|
pwszLogonDomainDnsName = Malloc(sizeof(WCHAR) * cchLogonDomainDnsName);
|
|
ZeroMemory(pwszLogonDomainDnsName, sizeof(WCHAR) * cchLogonDomainDnsName);
|
|
cchLogonDomainDnsName = GetEnvironmentVariableW(c_wszUserDnsDomain,
|
|
pwszLogonDomainDnsName,
|
|
cchLogonDomainDnsName);
|
|
}
|
|
|
|
// Save the name of this domain as a domain to test.
|
|
// ------------------------------------------------------------
|
|
if (cchLogonDomainDnsName && pwszLogonDomainDnsName && lstrlenW(pwszLogonDomainDnsName))
|
|
{
|
|
pResults->Global.pLogonDomain = AddTestedDomain( pParams, pResults,
|
|
pResults->Global.pLogonDomainName->Buffer,
|
|
pwszLogonDomainDnsName,
|
|
FALSE );
|
|
}
|
|
else
|
|
{
|
|
pResults->Global.pLogonDomain = AddTestedDomain( pParams, pResults,
|
|
pResults->Global.pLogonDomainName->Buffer,
|
|
NULL,
|
|
FALSE );
|
|
}
|
|
|
|
if (pwszLogonDomainDnsName)
|
|
Free(pwszLogonDomainDnsName);
|
|
|
|
if ( pResults->Global.pLogonDomain == NULL )
|
|
{
|
|
PrintStatusMessage(pParams,0, IDS_GLOBAL_FAIL_NL);
|
|
pResults->Global.hrMemberTestResult = S_FALSE;
|
|
goto Cleanup;
|
|
}
|
|
|
|
}
|
|
|
|
//
|
|
// Get the name of the logon server.
|
|
//
|
|
LogonServerLength = GetEnvironmentVariableW(
|
|
L"LOGONSERVER",
|
|
swzLogonServer,
|
|
DimensionOf(swzLogonServer));
|
|
if ( LogonServerLength != 0 )
|
|
{
|
|
//
|
|
// If the caller was supposed to logon to a domain,
|
|
// and this isn't a DC,
|
|
// see if the user logged on with cached credentials.
|
|
//
|
|
if ( pResults->Global.pLogonDomain != NULL &&
|
|
pPrimaryDomain->MachineRole != DsRole_RoleBackupDomainController &&
|
|
pPrimaryDomain->MachineRole != DsRole_RolePrimaryDomainController ) {
|
|
LPWSTR pswzLogonServer;
|
|
|
|
if ( swzLogonServer[0] == L'\\' && swzLogonServer[1] == L'\\')
|
|
{
|
|
pswzLogonServer = &swzLogonServer[2];
|
|
}
|
|
else
|
|
{
|
|
pswzLogonServer = &swzLogonServer[0];
|
|
}
|
|
|
|
pResults->Global.pswzLogonServer = _wcsdup(swzLogonServer);
|
|
|
|
if ( _wcsicmp( pResults->Global.swzNetBiosName, pswzLogonServer ) == 0 )
|
|
{
|
|
pResults->Global.fLogonWithCachedCredentials = TRUE;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (pPrimaryDomain->DomainNameFlat == NULL)
|
|
{
|
|
// the NetBIOS name is not specified
|
|
if (FHrSucceeded(pResults->Global.hrMemberTestResult))
|
|
pResults->Global.hrMemberTestResult = S_FALSE;
|
|
}
|
|
|
|
PrintStatusMessage(pParams,0, IDS_GLOBAL_PASS_NL);
|
|
|
|
Cleanup:
|
|
|
|
if ( pPolicyDomainInfo != NULL ) {
|
|
(void) LsaFreeMemory((PVOID) pPolicyDomainInfo);
|
|
}
|
|
if ( PolicyHandle != NULL ) {
|
|
(void) LsaClose(PolicyHandle);
|
|
}
|
|
|
|
return pResults->Global.hrMemberTestResult;
|
|
}
|
|
|
|
//Check if System Volume is ready
|
|
//Author: NSun
|
|
BOOL IsSysVolReady(NETDIAG_PARAMS* pParams)
|
|
{
|
|
DWORD dwData = 1;
|
|
DWORD dwSize = sizeof(dwData);
|
|
LONG lRet;
|
|
BOOL fRetVal = TRUE;
|
|
HKEY hkeyNetLogonParams = NULL;
|
|
|
|
lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
|
|
c_szRegNetLogonParams,
|
|
0,
|
|
KEY_READ,
|
|
&hkeyNetLogonParams);
|
|
|
|
if (ERROR_SUCCESS == lRet)
|
|
{
|
|
//it's ok that the SysVolReady value doesn't exist
|
|
if (ReadRegistryDword(hkeyNetLogonParams,
|
|
c_szRegSysVolReady,
|
|
&dwData))
|
|
{
|
|
if (0 == dwData)
|
|
fRetVal = FALSE;
|
|
}
|
|
|
|
RegCloseKey(hkeyNetLogonParams);
|
|
}
|
|
else
|
|
PrintDebugSz(pParams, 0, _T("Failed to open the registry of NetLogon parameters.\n"));
|
|
|
|
return fRetVal;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
MemberGlobalPrint
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
void MemberGlobalPrint(IN NETDIAG_PARAMS *pParams,
|
|
IN OUT NETDIAG_RESULT *pResults)
|
|
{
|
|
PDSROLE_PRIMARY_DOMAIN_INFO_BASIC pPrimaryDomain = NULL;
|
|
BOOL fDomain = TRUE;
|
|
TCHAR szName[256];
|
|
int ids;
|
|
|
|
if (pParams->fVerbose || !FHrOK(pResults->Global.hrMemberTestResult))
|
|
{
|
|
PrintNewLine(pParams, 2);
|
|
PrintTestTitleResult(pParams, IDS_MEMBER_LONG, IDS_MEMBER_SHORT, TRUE,
|
|
pResults->Global.hrMemberTestResult, 0);
|
|
}
|
|
|
|
pPrimaryDomain = pResults->Global.pPrimaryDomainInfo;
|
|
|
|
if (!pPrimaryDomain)
|
|
goto L_ERROR;
|
|
|
|
//Bug 293635, check whether system volume is ready if the machine is a DC
|
|
if (pResults->Global.fSysVolNotReady &&
|
|
(DsRole_RoleBackupDomainController == pPrimaryDomain->MachineRole ||
|
|
DsRole_RolePrimaryDomainController == pPrimaryDomain->MachineRole))
|
|
{
|
|
PrintMessage(pParams, IDS_MEMBER_SYSVOL_NOT_READY);
|
|
}
|
|
|
|
if (pParams->fReallyVerbose)
|
|
//IDS_MEMBER_11208 " Machine is a: "
|
|
PrintMessage(pParams, IDS_MEMBER_11208 );
|
|
|
|
switch ( pPrimaryDomain->MachineRole )
|
|
{
|
|
case DsRole_RoleStandaloneWorkstation:
|
|
// IDS_MEMBER_11209 "Standalone Workstation"
|
|
ids = IDS_MEMBER_11209;
|
|
fDomain = FALSE;
|
|
break;
|
|
case DsRole_RoleMemberWorkstation:
|
|
// IDS_MEMBER_11210 "Member Workstation"
|
|
ids = IDS_MEMBER_11210;
|
|
fDomain = TRUE;
|
|
break;
|
|
case DsRole_RoleStandaloneServer:
|
|
// IDS_MEMBER_11211 "Standalone Server"
|
|
ids = IDS_MEMBER_11211;
|
|
fDomain = FALSE;
|
|
break;
|
|
case DsRole_RoleMemberServer:
|
|
// IDS_MEMBER_11212 "Member Server"
|
|
ids = IDS_MEMBER_11212;
|
|
fDomain = TRUE;
|
|
break;
|
|
case DsRole_RoleBackupDomainController:
|
|
// IDS_MEMBER_11213 "Backup Domain Controller"
|
|
ids = IDS_MEMBER_11213;
|
|
fDomain = TRUE;
|
|
break;
|
|
case DsRole_RolePrimaryDomainController:
|
|
// IDS_MEMBER_11214 "Primary Domain Controller"
|
|
ids = IDS_MEMBER_11214;
|
|
fDomain = TRUE;
|
|
break;
|
|
default:
|
|
if (pParams->fReallyVerbose)
|
|
{
|
|
// IDS_MEMBER_11215 "<Unknown Role> %ld"
|
|
PrintMessage(pParams, IDS_MEMBER_11215,
|
|
pPrimaryDomain->MachineRole );
|
|
}
|
|
ids = 0;
|
|
fDomain = TRUE;
|
|
break;
|
|
}
|
|
|
|
if (pParams->fReallyVerbose && ids)
|
|
PrintMessage(pParams, ids);
|
|
|
|
if (pParams->fReallyVerbose)
|
|
PrintNewLine(pParams, 1);
|
|
|
|
if ( pPrimaryDomain->DomainNameFlat == NULL )
|
|
{
|
|
// IDS_MEMBER_11217 " Netbios Domain name is not specified: "
|
|
// IDS_MEMBER_11232 " Netbios Workgroup name is not specified: "
|
|
ids = fDomain ? IDS_MEMBER_11217 : IDS_MEMBER_11232;
|
|
|
|
PrintMessage(pParams, ids);
|
|
}
|
|
else
|
|
{
|
|
// IDS_MEMBER_11216 " Netbios Domain name: %ws\n"
|
|
// IDS_MEMBER_11218 " Netbios Workgroup name: %ws\n"
|
|
ids = fDomain ? IDS_MEMBER_11216 : IDS_MEMBER_11218;
|
|
|
|
if (pParams->fReallyVerbose)
|
|
PrintMessage(pParams, ids,
|
|
pPrimaryDomain->DomainNameFlat );
|
|
}
|
|
|
|
if ( pPrimaryDomain->DomainNameDns == NULL )
|
|
{
|
|
// IDS_MEMBER_11219 " Dns domain name is not specified.\n"
|
|
PrintMessage(pParams, IDS_MEMBER_11219 );
|
|
}
|
|
else
|
|
{
|
|
if (pParams->fReallyVerbose)
|
|
// IDS_MEMBER_11220 " Dns domain name: %ws\n"
|
|
PrintMessage(pParams, IDS_MEMBER_11220,
|
|
pPrimaryDomain->DomainNameDns );
|
|
}
|
|
|
|
if ( pPrimaryDomain->DomainForestName == NULL )
|
|
{
|
|
// IDS_MEMBER_11221 " Dns forest name is not specified.\n"
|
|
PrintMessage(pParams, IDS_MEMBER_11221 );
|
|
}
|
|
else
|
|
{
|
|
if (pParams->fReallyVerbose)
|
|
// IDS_MEMBER_11222 " Dns forest name: %ws\n"
|
|
PrintMessage(pParams, IDS_MEMBER_11222,
|
|
pPrimaryDomain->DomainForestName );
|
|
}
|
|
|
|
|
|
if ( pParams->fReallyVerbose )
|
|
{
|
|
WCHAR swzGuid[64];
|
|
|
|
// IDS_MEMBER_11223 " Domain Guid: "
|
|
PrintMessage(pParams, IDS_MEMBER_11223);
|
|
StringFromGUID2(&pPrimaryDomain->DomainGuid,
|
|
swzGuid,
|
|
DimensionOf(swzGuid));
|
|
PrintMessage(pParams, IDS_GLOBAL_WSTRING, swzGuid);
|
|
PrintNewLine(pParams, 1);
|
|
|
|
if ( pPrimaryDomain->MachineRole != DsRole_RoleStandaloneWorkstation &&
|
|
pPrimaryDomain->MachineRole != DsRole_RoleStandaloneServer )
|
|
{
|
|
// IDS_MEMBER_11227 " Domain Sid: "
|
|
PrintMessage(pParams, IDS_MEMBER_11227);
|
|
PrintSid( pParams, pResults->Global.pMemberDomain->DomainSid );
|
|
}
|
|
|
|
// IDS_MEMBER_11228 " Logon User: %wZ\n"
|
|
PrintMessage(pParams, IDS_MEMBER_11228, pResults->Global.pLogonUser );
|
|
// IDS_MEMBER_11229 " Logon Domain: %wZ\n"
|
|
PrintMessage(pParams, IDS_MEMBER_11229, pResults->Global.pLogonDomainName );
|
|
}
|
|
|
|
if ( pParams->fReallyVerbose)
|
|
{
|
|
if (pResults->Global.pswzLogonServer &&
|
|
pResults->Global.pswzLogonServer[0])
|
|
// IDS_MEMBER_11230 " Logon Server: %ws\n"
|
|
PrintMessage(pParams, IDS_MEMBER_11230, pResults->Global.pswzLogonServer );
|
|
|
|
if (pResults->Global.fLogonWithCachedCredentials)
|
|
{
|
|
// IDS_MEMBER_11231 " [WARNING] Member: User was logged on with cached credentials\n"
|
|
PrintMessage(pParams, IDS_MEMBER_11231);
|
|
}
|
|
}
|
|
|
|
L_ERROR:
|
|
return;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
MemberPerInterfacePrint
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
void MemberPerInterfacePrint(IN NETDIAG_PARAMS *pParams,
|
|
IN NETDIAG_RESULT *pResults,
|
|
IN INTERFACE_RESULT *pIfResult)
|
|
{
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
MemberCleanup
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
void MemberCleanup(IN NETDIAG_PARAMS *pParams,
|
|
IN OUT NETDIAG_RESULT *pResults)
|
|
{
|
|
free(pResults->Global.pswzLogonServer);
|
|
pResults->Global.pswzLogonServer = NULL;
|
|
}
|