|
|
// Copyright (C) 1997 Microsoft Corporation
//
// wizard state object
//
// 12-15-97 sburns
#include "headers.hxx"
#include "state.hpp"
#include "resource.h"
#include "ds.hpp"
#include "common.hpp"
static const String SECTION_NAME(L"DCInstall"); const String State::OPTION_NEW_DOMAIN_NAME(L"NewDomainDNSName"); const String State::OPTION_SITE_NAME(L"SiteName"); const String State::OPTION_PARENT_DOMAIN_NAME(L"ParentDomainDNSName"); const String State::OPTION_CHILD_NAME(L"ChildName");
const String State::OPTION_DNS_ON_NET(L"DNSOnNetwork");
const String State::OPTION_REPLICA_OR_NEW_DOMAIN(L"ReplicaOrNewDomain"); const String State::VALUE_DOMAIN(L"Domain");
const String State::OPTION_REPLICA_OR_MEMBER(L"ReplicaOrMember"); const String State::VALUE_REPLICA(L"Replica");
const String State::OPTION_NEW_DOMAIN(L"NewDomain"); const String State::VALUE_CHILD(L"Child"); const String State::VALUE_TREE(L"Tree");
const String State::OPTION_NEW_DOMAIN_NETBIOS_NAME(L"DomainNetbiosName"); const String State::OPTION_DATABASE_PATH(L"DatabasePath"); const String State::OPTION_LOG_PATH(L"LogPath"); const String State::OPTION_SYSVOL_PATH(L"SYSVOLPath"); const String State::OPTION_REPLICA_DOMAIN_NAME(L"ReplicaDomainDNSName");
const String State::OPTION_IS_LAST_DC(L"IsLastDCInDomain"); const String State::VALUE_YES(L"Yes"); const String State::VALUE_NO(L"No");
const String State::OPTION_ADMIN_PASSWORD(L"AdministratorPassword"); const String State::OPTION_REBOOT(L"RebootOnSuccess"); const String State::VALUE_NO_DONT_PROMPT(L"NoAndNoPromptEither");
const String State::OPTION_USERNAME(L"UserName"); const String State::OPTION_PASSWORD(L"Password"); const String State::OPTION_USER_DOMAIN(L"UserDomain");
const String State::OPTION_AUTO_CONFIG_DNS(L"AutoConfigDNS");
const String State::OPTION_ALLOW_ANON_ACCESS(L"AllowAnonymousAccess"); const String State::OPTION_REPLICATION_SOURCE(L"ReplicationSourceDC"); const String State::OPTION_SAFE_MODE_ADMIN_PASSWORD(L"SafeModeAdminPassword"); const String State::OPTION_CRITICAL_REPLICATION_ONLY(L"CriticalReplicationOnly");
const String State::OPTION_SOURCE_PATH(L"ReplicationSourcePath"); const String State::OPTION_SYSKEY(L"Syskey"); const String State::OPTION_GC_CONFIRM(L"ConfirmGc"); const String State::OPTION_SET_FOREST_VERSION("SetForestVersion");
static State* stateInstance;
void State::Init() { ASSERT(!stateInstance);
stateInstance = new State; }
void State::Destroy() { delete stateInstance; };
State& State::GetInstance() { ASSERT(stateInstance);
return *stateInstance; }
// Determines the full file path of the folder where administration (incl. DS)
// tools shortcuts are placed. On success, returns S_OK and sets result to
// the path. On failure, returns a COM error and sets results to empty.
//
// result - receives the folder path on success.
HRESULT GetAdminToolsPath(String& result) { LOG_FUNCTION(GetAdminToolsPath);
result.erase();
TCHAR buf[MAX_PATH]; HRESULT hr = ::SHGetFolderPath( 0, CSIDL_COMMON_ADMINTOOLS, 0, SHGFP_TYPE_CURRENT, buf);
if (SUCCEEDED(hr)) { result = buf; }
return hr; }
State::State() : adminPassword(), allowAnonAccess(false), answerFile(0), autoConfigDns(false), computer(), context(), dbPath(), domainsInForest(), failureMessage(), finishMessages(), installedSite(), isAdvancedMode(false), isBackupGc(false), isDnsOnNet(true), isLastDc(false), isUpgrade(false), logPath(), needsCommandLineHelp(false), needsReboot(false), newDomainDnsName(), newDomainFlatName(), operation(NONE), operationResultsMessage(), operationResultsStatus(FAILURE), operationResultsFlags(0), parentDomainDnsName(), password(), reinstallDomain(false), reinstallDomainController(false), replicaDnsDomainName(), replicateFromMedia(false), replicationPartnerDc(), restoreGc(false), runHiddenWhileUnattended(true), safeModeAdminPassword(), setForestVersion(false), shortcutPath(), siteName(), splash(0), sourcePath(), sysvolPath(), syskey(), syskeyLocation(STORED), useCurrentCredentials(false), userDomain(), userForest(), username() { LOG_CTOR(State);
ArgMap args; MapCommandLineArgs(args);
if (args.size() < 2) { LOG(L"no options specified"); } else { // check for answerfile specification
static const wchar_t* ANSWER1 = L"answer"; static const wchar_t* ANSWER2 = L"u"; static const wchar_t* ANSWER3 = L"upgrade";
if ( args.find(ANSWER1) != args.end() || args.find(ANSWER2) != args.end() || args.find(ANSWER3) != args.end() ) { bool isDefaultAnswerfile = false;
String filename = args[ANSWER1]; if (filename.empty()) { filename = args[ANSWER2]; } if (filename.empty()) { filename = args[ANSWER3]; } if (filename.empty()) { // default value if none specified
filename = L"%systemdrive%\\dcpromo-ntupg.inf";
// if this file does not exist, don't pop up an error message.
isDefaultAnswerfile = true; }
SetupAnswerFile(filename, isDefaultAnswerfile);
args.erase(ANSWER1); args.erase(ANSWER2); args.erase(ANSWER3); }
// check for /adv
static const wchar_t* ADV = L"adv";
if (args.find(ADV) != args.end()) { LOG(L"Enabling advanced mode");
isAdvancedMode = true; args.erase(ADV); }
// anything left over gets you command line help, (one arg will always
// remain: the name of the exe)
if (args.size() > 1) { LOG(L"Unrecognized command line options specified");
needsCommandLineHelp = true; } }
HRESULT hr = computer.Refresh();
// we're confident this will work, as the computer refers to the
// local machine.
ASSERT(SUCCEEDED(hr)); LOG_HRESULT(hr);
DetermineRunContext();
// Disable locking of the console as early as possible to narrow the
// window of opportunity for the user (or the system) to lock the
// console before a valid machine security state is reached. We do this
// early only for upgrades, because upgrades autologon and autostart
// dcpromo, and the console may sit idle for some time. 311161
if (context == PDC_UPGRADE || context == BDC_UPGRADE) { DisableConsoleLocking(); }
// We must call this at startup, because once a demote operation is
// complete, it may not be possible for the shell to determine this
// path. 366738
hr = GetAdminToolsPath(shortcutPath); ASSERT(SUCCEEDED(hr)); LOG_HRESULT(hr); }
void State::SetupAnswerFile(const String& filename, bool isDefaultAnswerfile) { LOG_FUNCTION2(State::SetupAnswerFile, filename);
String f(filename); if (f.find(L"\\") == String::npos) { // GetPrivateProfileString requires a path: use the current directory
// as a default path.
f = L".\\" + filename; }
LOG(L"answerfile specified: " + f);
f = Win::ExpandEnvironmentStrings(f);
LOG(L"answerfile resolved to: " + f);
// we don't use FS::PathExist here because that function expects a
// fully-qualified path. The path we have may be relative.
DWORD unused = 0; HRESULT hr = Win::GetFileAttributes(f, unused); if (SUCCEEDED(hr)) { // file found.
LOG(L"answerfile found"); answerFile = new AnswerFile(f);
splash = new UnattendSplashDialog(); splash->ModelessExecute(Win::GetDesktopWindow()); } else { LOG(L"answerfile NOT found");
if (!isDefaultAnswerfile) { popup.Error( Win::GetDesktopWindow(), String::format(IDS_ANSWERFILE_NOT_FOUND, f.c_str())); } } }
#ifdef LOGGING_BUILD
static const String CONTEXTS[] = { L"NT5_DC", L"NT5_STANDALONE_SERVER", L"NT5_MEMBER_SERVER", L"BDC_UPGRADE", L"PDC_UPGRADE" }; #endif
void State::DetermineRunContext() { LOG_FUNCTION(State::DetermineRunContext);
DS::PriorServerRole priorRole = DS::GetPriorServerRole(isUpgrade);
if (isUpgrade && priorRole != DS::UNKNOWN) { switch (priorRole) { case DS::PDC: { context = PDC_UPGRADE; break; } case DS::BDC: { context = BDC_UPGRADE; break; } default: { ASSERT(false); break; } } } else { switch (computer.GetRole()) { case Computer::STANDALONE_SERVER: { context = NT5_STANDALONE_SERVER; break; } case Computer::MEMBER_SERVER: { context = NT5_MEMBER_SERVER; break; } case Computer::PRIMARY_CONTROLLER: case Computer::BACKUP_CONTROLLER: { // we're already an NT5 DC
context = NT5_DC; break; } case Computer::STANDALONE_WORKSTATION: case Computer::MEMBER_WORKSTATION: default: { // we checked for this at startup
ASSERT(false); break; } } }
LOG(CONTEXTS[context]); }
State::~State() { LOG_DTOR(State);
delete answerFile;
// closes the splash dialog, if visible.
delete splash; }
State::RunContext State::GetRunContext() const { LOG_FUNCTION2(State::GetRunContext, CONTEXTS[context]);
return context; }
bool State::UsingAnswerFile() const { return answerFile != 0; }
bool IsPasswordOption(const String& option) { if ( option.icompare(State::OPTION_PASSWORD) == 0 || option.icompare(State::OPTION_ADMIN_PASSWORD) == 0 || option.icompare(State::OPTION_SYSKEY) == 0 || option.icompare(State::OPTION_SAFE_MODE_ADMIN_PASSWORD) == 0) // 142313
{ return true; }
return false; }
String State::GetAnswerFileOption(const String& option) const { LOG_FUNCTION2(GetAnswerFileOption, option); ASSERT(UsingAnswerFile());
String result; if (answerFile) { result = answerFile->ReadKey(SECTION_NAME, option);
// wipe out passwords as they are read.
if (IsPasswordOption(option)) { // caller should be using GetEncodedAnswerFileOption
ASSERT(false); if (answerFile->IsKeyPresent(SECTION_NAME, option)) { answerFile->WriteKey(SECTION_NAME, option, String()); } } else { // only trace non-password fields.
LOG(result); } }
return result; }
EncodedString State::GetEncodedAnswerFileOption(const String& option) const { LOG_FUNCTION2(GetEncodedAnswerFileOption, option); ASSERT(UsingAnswerFile());
EncodedString result; if (answerFile) { result = answerFile->EncodedReadKey(SECTION_NAME, option);
// wipe out passwords as they are read.
if (IsPasswordOption(option)) { if (answerFile->IsKeyPresent(SECTION_NAME, option)) { answerFile->WriteKey(SECTION_NAME, option, String()); } } else { // should only use the Encoded function for passwords
ASSERT(false); } }
return result; }
#ifdef LOGGING_BUILD
static const String OPERATIONS[] = { L"NONE", L"REPLICA", L"FOREST", L"TREE", L"CHILD", L"DEMOTE", L"ABORT_BDC_UPGRADE" }; #endif
void State::SetOperation(Operation oper) { LOG_FUNCTION2(State::SetOperation, OPERATIONS[oper]);
operation = oper; }
State::Operation State::GetOperation() const { LOG_FUNCTION2(State::GetOperation, OPERATIONS[operation]);
// if aborting BDC upgrade, context must be BDC upgrade
ASSERT(operation == ABORT_BDC_UPGRADE ? context == BDC_UPGRADE : true);
return operation; }
void State::SetReplicaDomainDNSName(const String& dnsName) { LOG_FUNCTION2(State:::SetReplicaDomainDNSName, dnsName); ASSERT(!dnsName.empty());
replicaDnsDomainName = dnsName;
// if the user is changing the domain to be replicated, then any
// previous replication partner DC may no longer apply.
// see ntbug9 #158726
SetReplicationPartnerDC(L""); }
String State::GetDatabasePath() const { LOG_FUNCTION2(State::GetDatabasePath, dbPath);
return dbPath; }
String State::GetLogPath() const { LOG_FUNCTION2(State::GetLogPath, logPath);
return logPath; }
String State::GetSYSVOLPath() const { LOG_FUNCTION2(State::GetSYSVOLPath, sysvolPath);
return sysvolPath; }
void State::SetDatabasePath(const String& path) { LOG_FUNCTION2(State::SetDatabasePath, path); ASSERT(!path.empty());
dbPath = path; }
void State::SetLogPath(const String& path) { LOG_FUNCTION2(State::SetLogPath, path); ASSERT(!path.empty());
logPath = path; }
void State::SetSYSVOLPath(const String& path) { LOG_FUNCTION2(State::SetSYSVOLPath, path); ASSERT(!path.empty());
sysvolPath = path; }
String State::GetUsername() const { LOG_FUNCTION2(State::GetUsername, username);
// don't assert that this is !empty -- we may use existing credentials
return username; }
EncodedString State::GetPassword() const { // don't log the password...
LOG_FUNCTION(State::GetPassword);
// don't assert that this is !empty -- we may use existing credentials
return password; }
void State::SetUsername(const String& name) { LOG_FUNCTION2(State::SetUsername, name); ASSERT(!name.empty());
username = name; }
void State::SetPassword(const EncodedString& password_) { LOG_FUNCTION(State::SetPassword); // password_ may be empty
// ASSERT(!password_.empty());
password = password_; }
String State::GetReplicaDomainDNSName() const { LOG_FUNCTION2( State::GetReplicaDomainDNSName, replicaDnsDomainName);
return replicaDnsDomainName; }
String State::GetSiteName() const { LOG_FUNCTION2(State::GetSiteName, siteName);
return siteName; }
void State::SetSiteName(const String& site) { LOG_FUNCTION2(State::SetSiteName, site); siteName = site; }
void State::SetOperationResults(OperationResult result) { LOG_FUNCTION2( State::SetOperationResults, String::format(L"result %1", result == SUCCESS ? L"SUCCESS" : L"FAILURE"));
operationResultsStatus = result; }
void State::SetOperationResultsMessage(const String& message) { LOG_FUNCTION2(State::SetOperationResultsMessage, message);
operationResultsMessage = message; }
String State::GetParentDomainDnsName() const { LOG_FUNCTION2( State::GetParentDomainDnsName, parentDomainDnsName);
return parentDomainDnsName; }
String State::GetNewDomainDNSName() const { LOG_FUNCTION2(State::GetNewDomainDNSName, newDomainDnsName);
return newDomainDnsName; }
String State::GetNewDomainNetbiosName() const { LOG_FUNCTION2( State::GetNewDomainNetbiosName, newDomainFlatName);
return newDomainFlatName; }
void State::SetParentDomainDNSName(const String& name) { LOG_FUNCTION2(State::SetParentDomainDNSName, name); ASSERT(!name.empty());
parentDomainDnsName = name; }
void State::SetNewDomainDNSName(const String& name) { LOG_FUNCTION2(State::SetNewDomainDNSName, name); ASSERT(!name.empty());
newDomainDnsName = name;
// This will cause the flat name to be re-generated
newDomainFlatName.erase(); }
void State::SetNewDomainNetbiosName(const String& name) { LOG_FUNCTION2(State::SetNewDomainNetbiosName, name); ASSERT(!name.empty());
newDomainFlatName = name; }
void State::SetUserDomainName(const String& name) { LOG_FUNCTION2(State::SetUserDomainName, name);
// name may be empty;
userDomain = name; }
String State::GetUserDomainName() const { LOG_FUNCTION2(State::GetUserDomainName, userDomain);
return userDomain; }
void State::ClearHiddenWhileUnattended() { LOG_FUNCTION(State::ClearHiddenWhileUnattended);
runHiddenWhileUnattended = false;
// closes the splash dialog, if visible.
if (splash) { // this will delete splash, too
splash->SelfDestruct(); splash = 0; } }
bool State::RunHiddenUnattended() const { // LOG_FUNCTION(State::RunHiddenUnattended);
return UsingAnswerFile() && runHiddenWhileUnattended; }
bool State::IsLastDCInDomain() const { LOG_FUNCTION2(State::IsLastDCInDomain, isLastDc ? L"true" : L"false");
return isLastDc; }
void State::SetIsLastDCInDomain(bool yesNo) { LOG_FUNCTION2( State::SetIsLastDCInDomain, yesNo ? L"is last dc" : L"is NOT last dc");
isLastDc = yesNo; }
void State::SetAdminPassword(const EncodedString& password) { LOG_FUNCTION(State::SetAdminPassword);
adminPassword = password; }
EncodedString State::GetAdminPassword() const { LOG_FUNCTION(State::GetAdminPassword);
return adminPassword; }
String State::GetOperationResultsMessage() const { LOG_FUNCTION2( State::GetOperationResultsMessage, operationResultsMessage);
return operationResultsMessage; }
State::OperationResult State::GetOperationResultsCode() const { LOG_FUNCTION2( State::GetOperationResultsCode, operationResultsStatus == SUCCESS ? L"SUCCESS" : L"FAILURE");
return operationResultsStatus; }
bool State::AutoConfigureDNS() const { LOG_FUNCTION2( State::AutoConfigureDNS, autoConfigDns ? L"true" : L"false");
return autoConfigDns; }
void State::SetAutoConfigureDNS(bool yesNo) { LOG_FUNCTION2( State::SetAutoConfigureDNS, yesNo ? L"true" : L"false");
autoConfigDns = yesNo; }
bool State::IsDNSOnNetwork() const { LOG_FUNCTION2( State::IsDNSOnNetwork, isDnsOnNet ? L"true" : L"false");
return isDnsOnNet; }
void State::SetDNSOnNetwork(bool yesNo) { LOG_FUNCTION2( State::SetDNSOnNetwork, yesNo ? L"true" : L"false");
isDnsOnNet = yesNo; }
String State::GetInstalledSite() const { LOG_FUNCTION2(State::GetInstalledSite, installedSite);
// should be set before we ask for it...
ASSERT(!installedSite.empty());
return installedSite; }
void State::SetInstalledSite(const String& site) { LOG_FUNCTION2(State::SetInstalledSite, site); ASSERT(!site.empty());
installedSite = site; }
void State::AddFinishMessage(const String& message) { LOG_FUNCTION2(State::AddFinishMessage, message); ASSERT(!message.empty());
if (finishMessages.empty()) { finishMessages += message; } else { // add a blank line between each message
finishMessages += L"\r\n\r\n" + message; } }
String State::GetFinishMessages() const { LOG_FUNCTION2(State::GetFinishMessages, finishMessages);
return finishMessages; }
Computer& State::GetComputer() { return computer; }
void State::SetFailureMessage(const String& message) { LOG_FUNCTION2(State::SetFailureMessage, message); ASSERT(!message.empty());
failureMessage = message; }
String State::GetFailureMessage() const { LOG_FUNCTION2(State::GetFailureMessage, failureMessage);
return failureMessage; }
bool State::ShouldInstallAndConfigureDns() const { if (AutoConfigureDNS() || !IsDNSOnNetwork()) { return true; }
return false; }
String State::GetUserForestName() const { LOG_FUNCTION2(State::GetUserForestName, userForest); ASSERT(!userForest.empty());
return userForest; }
void State::SetUserForestName(const String& forest) { LOG_FUNCTION2(State::SetUserForestName, forest); ASSERT(!forest.empty());
userForest = forest; }
bool State::IsDomainInForest(const String& domain) const { LOG_FUNCTION2(State::IsDomainInForest, domain); ASSERT(!domain.empty());
for ( DomainList::iterator i = domainsInForest.begin(); i != domainsInForest.end(); i++) { DNS_NAME_COMPARE_STATUS compare = Dns::CompareNames(*i, domain); if (compare == DnsNameCompareEqual) { LOG(L"domain is in forest"); return true; } }
return false; }
HRESULT State::ReadDomains() { LOG_FUNCTION(State::ReadDomains);
domainsInForest.clear(); return ::ReadDomains(domainsInForest); }
DNS_NAME_COMPARE_STATUS State::DomainFitsInForest(const String& domain, String& conflictingDomain) { LOG_FUNCTION(domainFitsInForest); ASSERT(!domain.empty());
conflictingDomain.erase();
DNS_NAME_COMPARE_STATUS relation = DnsNameCompareNotEqual; for ( DomainList::iterator i = domainsInForest.begin(); i != domainsInForest.end(); i++) { relation = Dns::CompareNames(domain, *i); switch (relation) { case DnsNameCompareNotEqual: { continue; } case DnsNameCompareEqual: { ASSERT(domain == *i); // fall thru
} case DnsNameCompareLeftParent: case DnsNameCompareRightParent: case DnsNameCompareInvalid: default: { conflictingDomain = *i; break; } }
break; }
return relation; }
bool State::GetDomainReinstallFlag() const { LOG_FUNCTION2( State::GetDomainReinstallFlag, reinstallDomain ? L"true" : L"false");
return reinstallDomain; }
void State::SetDomainReinstallFlag(bool newValue) { LOG_FUNCTION2( State::SetDomainReinstallFlag, newValue ? L"true" : L"false");
reinstallDomain = newValue; }
bool State::ShouldAllowAnonymousAccess() const { LOG_FUNCTION2( State::ShouldAllowAnonymousAccess, allowAnonAccess ? L"true" : L"false"); return allowAnonAccess; }
void State::SetShouldAllowAnonymousAccess(bool yesNo) { LOG_FUNCTION2( State::ShouldAllowAnonymousAccess, yesNo ? L"true" : L"false");
allowAnonAccess = yesNo; }
String State::GetReplicationPartnerDC() const { LOG_FUNCTION2(State::GetReplicationPartnerDC, replicationPartnerDc);
return replicationPartnerDc; }
void State::SetReplicationPartnerDC(const String dcName) { LOG_FUNCTION2(State::SetReplicationPartnerDC, dcName);
replicationPartnerDc = dcName; }
// Retrieve domain controller info for all DCs in the domain that this dc
// is a controller. (The result set should include this dc)
// Caller should free the result with DsFreeDomainControllerInfo
HRESULT State::GetDomainControllerInfoForMyDomain( DS_DOMAIN_CONTROLLER_INFO_2W*& info, DWORD& dcCount) { LOG_FUNCTION(State::GetDomainControllerInfoForMyDomain);
// if this assertion does not hold, then the DsBind call below should
// fail.
ASSERT(GetComputer().IsDomainController());
dcCount = 0; info = 0;
HRESULT hr = S_OK; HANDLE hds = 0; do { String domainDnsName = GetComputer().GetDomainDnsName(); String dcName = Win::GetComputerNameEx(ComputerNameDnsFullyQualified);
ASSERT(!domainDnsName.empty()); ASSERT(!dcName.empty());
// Bind to self
hr = MyDsBind( dcName, domainDnsName, hds); BREAK_ON_FAILED_HRESULT(hr);
// find all the dc's for my domain. the list should contain dcName.
// level 2 contains the "is gc" flag
hr = MyDsGetDomainControllerInfo( hds, domainDnsName, dcCount, info); BREAK_ON_FAILED_HRESULT(hr); } while (0);
if (hds) { ::DsUnBind(&hds); hds = 0; }
return hr; }
// returns true if no other domain controller for this DCs domain can be
// found in the DS. False otherwise
bool State::IsReallyLastDcInDomain() { LOG_FUNCTION(State::IsReallyLastDcInDomain);
// Assume we are alone in the universe.
bool result = true;
do { // find all the dc's for my domain. the list should contain dcName.
DS_DOMAIN_CONTROLLER_INFO_2W* info = 0; DWORD count = 0;
HRESULT hr = GetDomainControllerInfoForMyDomain(info, count); BREAK_ON_FAILED_HRESULT(hr);
ASSERT(count); ASSERT(info);
// if there are more than 1 entry (more than the one for this dc),
// then the DS believes that there are other DCs for this domain.
if (count > 1) { result = false; }
#ifdef DBG
// double check that we found ourselves.
if (result && info[0].DnsHostName) { LOG(info[0].DnsHostName);
String dcName = Win::GetComputerNameEx(ComputerNameDnsFullyQualified);
ASSERT( Dns::CompareNames(info[0].DnsHostName, dcName) == DnsNameCompareEqual); }
#endif
MyDsFreeDomainControllerInfo(count, info); } while (0); LOG( String::format( L"This box %1 the sole DC for the domain", result ? L"is" : L"is NOT"));
return result; }
// Returns true if this computer is a global catalog
bool State::IsGlobalCatalog() { LOG_FUNCTION(State::IsGlobalCatalog);
if (!GetComputer().IsDomainController()) { // can't possibly be a GC if not a DC
return false; }
bool result = false; do { String dcName = Win::GetComputerNameEx(ComputerNameDnsFullyQualified);
// find all the dc's for my domain. the list should contain dcName.
// level 2 contains the "is gc" flag
DS_DOMAIN_CONTROLLER_INFO_2W* info = 0; DWORD count = 0;
HRESULT hr = GetDomainControllerInfoForMyDomain(info, count); BREAK_ON_FAILED_HRESULT(hr);
// there should be at least 1 entry (ourself)
ASSERT(count); ASSERT(info);
for (int i = 0; i < count; i++) { if (info[i].DnsHostName) // 340723
{ LOG(info[i].DnsHostName);
if ( Dns::CompareNames(info[i].DnsHostName, dcName) == DnsNameCompareEqual) { // we found ourselves in the list
LOG(L"found!"); result = info[i].fIsGc ? true : false; break; } } }
MyDsFreeDomainControllerInfo(count, info); } while (0);
LOG( String::format( L"This box %1 a global catalog", result ? L"is" : L"is NOT"));
return result; }
EncodedString State::GetSafeModeAdminPassword() const { LOG_FUNCTION(State::GetSafeModeAdminPassword);
// don't trace the password!
return safeModeAdminPassword; }
void State::SetSafeModeAdminPassword(const EncodedString& pwd) { LOG_FUNCTION(State::SetSafeModeAdminPassword);
// don't trace the password!
// pwd may be empty.
safeModeAdminPassword = pwd; }
String State::GetAdminToolsShortcutPath() const { LOG_FUNCTION2(State::GetAdminToolsShortcutPath, shortcutPath);
return shortcutPath; }
bool State::NeedsCommandLineHelp() const { return needsCommandLineHelp; }
bool State::IsAdvancedMode() const { return isAdvancedMode; }
void State::SetReplicateFromMedia(bool yesNo) { LOG_FUNCTION2( State::SetReplicateFromMedia, yesNo ? L"true" : L"false");
replicateFromMedia = yesNo; }
void State::SetReplicationSourcePath(const String& path) { LOG_FUNCTION2(State::SetReplicationSourcePath, path);
sourcePath = path; }
bool State::ReplicateFromMedia() const { LOG_FUNCTION2( State::ReplicateFromMedia, replicateFromMedia ? L"true" : L"false");
return replicateFromMedia; }
String State::GetReplicationSourcePath() const { LOG_FUNCTION2(State::GetReplicationSourcePath, sourcePath);
return sourcePath; }
void State::SetSyskeyLocation(SyskeyLocation loc) { LOG_FUNCTION2(State::SetSyskeyLocation, loc == DISK ? L"disk" : ((loc == PROMPT) ? L"prompt" : L"stored"));
syskeyLocation = loc; }
State::SyskeyLocation State::GetSyskeyLocation() const { LOG_FUNCTION2( State::IsSyskeyPresent, syskeyLocation == DISK ? L"disk" : ((syskeyLocation == PROMPT) ? L"prompt" : L"stored"));
return syskeyLocation; }
void State::SetIsBackupGc(bool yesNo) { LOG_FUNCTION2(State::SetIsBackupGc, yesNo ? L"true" : L"false");
isBackupGc = yesNo; }
bool State::IsBackupGc() const { LOG_FUNCTION2(State::IsBackupGc, isBackupGc ? L"true" : L"false");
return isBackupGc; }
void State::SetSyskey(const EncodedString& syskey_) { // don't log the syskey!
LOG_FUNCTION(State::SetSyskey); ASSERT(!syskey_.IsEmpty());
syskey = syskey_; }
EncodedString State::GetSyskey() const { // don't log the syskey!
LOG_FUNCTION(State::GetSyskey);
return syskey; }
void State::SetRestoreGc(bool yesNo) { LOG_FUNCTION2(State::SetRestoreGc, yesNo ? L"true" : L"false");
restoreGc = yesNo; }
bool State::GetRestoreGc() const { LOG_FUNCTION2(State::GetRestoreGc, restoreGc ? L"true" : L"false");
return restoreGc; }
bool State::IsSafeModeAdminPwdOptionPresent() const { LOG_FUNCTION(State::IsSafeModeAdminPwdOptionPresent); ASSERT(UsingAnswerFile());
bool result = false;
if (answerFile) { result = answerFile->IsKeyPresent( SECTION_NAME, OPTION_SAFE_MODE_ADMIN_PASSWORD); }
LOG(result ? L"true" : L"false");
return result; }
void State::SetDomainControllerReinstallFlag(bool newValue) { LOG_FUNCTION2( State::SetDomainControllerReinstallFlag, newValue ? L"true" : L"false");
reinstallDomainController = newValue; }
bool State::GetDomainControllerReinstallFlag() const { LOG_FUNCTION2( State::GetDomainControllerReinstallFlag, reinstallDomain ? L"true" : L"false");
return reinstallDomainController; }
void State::SetOperationResultsFlags(ULONG flags) { LOG_FUNCTION2( State::SetOperationResultsFlags, String::format(L"0x%1!X!", flags));
operationResultsFlags = flags; }
ULONG State::GetOperationResultsFlags() const { LOG_FUNCTION2( State::GetOperationResultsFlags, String::format(L"0x%1!X!", operationResultsFlags));
return operationResultsFlags; }
bool State::IsOperationRetryAllowed() const { LOG_FUNCTION(State::IsOperationRetryAllowed);
bool result = true; if (operationResultsFlags & DSROLE_IFM_RESTORED_DATABASE_FILES_MOVED) { // don't allow the user to retry the operation again, as one consequence
// of the failure is that the moved files are now trashed. The user
// must re-restore the files in order to attempt the operation again.
// NTRAID#NTBUG9-296872-2001/01/29-sburns
LOG(L"ifm files moved, retry not allowed");
result = false; }
LOG(result ? L"true" : L"false");
return result; }
// needing a reboot is a "sticky" setting: there's no way to turn it off.
// if you once needed to reboot the machine, you will always need to reboot
// the machine. (at least, for now).
void State::SetNeedsReboot() { LOG_FUNCTION(State::SetNeedsReboot); needsReboot = true; }
bool State::GetNeedsReboot() const { LOG_FUNCTION2(State::GetNeedsReboot, needsReboot ? L"true" : L"false");
return needsReboot; }
void State::SetSetForestVersionFlag(bool setVersion) { LOG_FUNCTION2( State::SetSetForestVersionFlag, setVersion ? L"true" : L"false");
setForestVersion = setVersion; }
bool State::GetSetForestVersionFlag() const { LOG_FUNCTION2( State::GetSetForestVersionFlag, setForestVersion ? L"true" : L"false");
return setForestVersion; }
|