//++ // // 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 " %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; }