windows-nt/Source/XPSP1/NT/net/ias/iasjet/setup/migratemdb.cpp
2020-09-26 16:20:57 +08:00

1121 lines
42 KiB
C++

/////////////////////////////////////////////////////////////////////////////
//
// Copyright(C) 1999-2000 Microsoft Corporation all rights reserved.
//
// Module: migratemdb.cpp
//
// Project: Windows 2000 IAS
//
// Description: IAS NT 4 MDB to IAS W2K MDB Migration Logic
//
// Author: TLP 1/13/1999
//
//
// Revision 02/24/2000 Moved to a separate dll
// 03/15/2000 Almost completely rewritten
//
/////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "Attributes.h"
#include "Clients.h"
#include "DefaultProvider.h"
#include "GlobalData.h"
#include "migratemdb.h"
#include "migrateregistry.h"
#include "Objects.h"
#include "Policy.h"
#include "Properties.h"
#include "Profiles.h"
#include "profileattributelist.h"
#include "Providers.h"
#include "proxyservergroupcollection.h"
#include "RadiusAttributeValues.h"
#include "Realms.h"
#include "RemoteRadiusServers.h"
#include "ServiceConfiguration.h"
#include "Version.h"
#include "updatemschap.h"
// To remember:
// IAS_MAX_VSA_LENGTH = (253 * 2);
// 1.0 Format Offsets
//VSA_OFFSET = 0;
//VSA_OFFSET_ID = 0;
//VSA_OFFSET_TYPE = 8;
//VSA_OFFSET_LENGTH = 10;
//VSA_OFFSET_VALUE_RFC = 12;
//VSA_OFFSET_VALUE_NONRFC = 8;
// 2.0 Format Offsets
//VSA_OFFSET_NEW = 2;
//VSA_OFFSET_ID_NEW = 2;
//VSA_OFFSET_TYPE_NEW = 10;
//VSA_OFFSET_LENGTH_NEW = 12;
//VSA_OFFSET_VALUE_NONRFC_NEW = 10;
//////////////////////////////////////////////////////////////////////////////
// Helper Functions
//////////////////////////////////////////////////////////////////////////////
/////// From inet.c in ias util directory /////////////
//////////
// Macro to test if a character is a digit.
//////////
#define IASIsDigit(p) ((_TUCHAR)(p - _T('0')) <= 9)
//////////
// Macro to strip one byte of an IP address from a character string.
// 'p' pointer to the string to be parsed
// 'ul' unsigned long that will receive the result.
//////////
#define STRIP_BYTE(p,ul) { \
if (!IASIsDigit(*p)) goto error; \
ul = *p++ - _T('0'); \
if (IASIsDigit(*p)) { \
ul *= 10; ul += *p++ - _T('0'); \
if (IASIsDigit(*p)) { \
ul *= 10; ul += *p++ - _T('0'); \
} \
} \
if (ul > 0xff) goto error; \
}
///////////////////////////////////////////////////////////////////////////////
//
// FUNCTION
//
// ias_inet_addr
//
// DESCRIPTION
//
// This function is similar to the WinSock inet_addr function (q.v.) except
// it returns the address in host order and it can operate on both ANSI
// and UNICODE strings.
//
///////////////////////////////////////////////////////////////////////////////
unsigned long __stdcall ias_inet_addr(const WCHAR* cp)
{
unsigned long token;
unsigned long addr;
STRIP_BYTE(cp,addr);
if (*cp++ != _T('.')) goto error;
STRIP_BYTE(cp,token);
if (*cp++ != _T('.')) goto error;
addr <<= 8;
addr |= token;
STRIP_BYTE(cp,token);
if (*cp++ != _T('.')) goto error;
addr <<= 8;
addr |= token;
STRIP_BYTE(cp,token);
addr <<= 8;
return addr | token;
error:
return 0xffffffff;
}
//////////////////////////////////////////////////////////////////////////////
// ConvertVSA
//////////////////////////////////////////////////////////////////////////////
void CMigrateMdb::ConvertVSA(
/*[in]*/ LPCWSTR pAttributeValueName,
/*[in]*/ LPCWSTR pAttrValue,
_bstr_t& NewString
)
{
const long IAS_MAX_VSA_LENGTH = (253 * 2);
const byte VSA_OFFSET = 0;
const byte VSA_OFFSET_NEW = 2;
const byte VSA_OFFSET_VALUE_RFC_NEW = 14;
wchar_t szNewValue[IAS_MAX_VSA_LENGTH + 1];
szNewValue[0] = '\0';
// RFC compliant integer
if ( ! lstrcmp(pAttributeValueName, L"URDecimal or Hexadecimal (0x.. "
L"format) Integer") )
{
// Add the "02" as the type to the head of the string
lstrcat(szNewValue,L"02");
// Copy the old value to the new
lstrcpy(szNewValue + VSA_OFFSET_NEW, pAttrValue + VSA_OFFSET);
// Strip of the "0x" if necessary and convert to decimal
if ( ! wcsncmp(&szNewValue[VSA_OFFSET_VALUE_RFC_NEW], L"0x", 2) )
{
lstrcpy(&szNewValue[VSA_OFFSET_VALUE_RFC_NEW],
&szNewValue[VSA_OFFSET_VALUE_RFC_NEW + 2] );
}
}
// RFC compliant string
else if ( ! lstrcmp(pAttributeValueName, L"URString") )
{
// Set the new string type to "01"
lstrcat(szNewValue,L"01");
// Copy the old string to the new
lstrcpy(szNewValue + VSA_OFFSET_NEW, pAttrValue + VSA_OFFSET);
// Convert the old hex formatted string to a BSTR (in place)
wchar_t wcSaved;
wchar_t* pXlatPos = &szNewValue[VSA_OFFSET_VALUE_RFC_NEW];
wchar_t* pNewCharPos = pXlatPos;
wchar_t* pEnd;
while ( *pXlatPos != '\0' )
{
wcSaved = *(pXlatPos + 2);
*(pXlatPos + 2) = '\0';
*pNewCharPos = (wchar_t) wcstol(pXlatPos, &pEnd, 16);
*(pXlatPos + 2) = wcSaved;
pXlatPos += 2;
++pNewCharPos;
}
*pNewCharPos = '\0';
}
// RFC compliant hex
else if ( ! lstrcmp(pAttributeValueName, L"URHexadecimal") )
{
// Set the new type and copy the old string to the new
lstrcat(szNewValue,L"03");
lstrcpy(szNewValue + VSA_OFFSET_NEW, pAttrValue + VSA_OFFSET);
}
// Non RFC compliant (always hex)
else if ( ! lstrcmp(pAttributeValueName, L"UHHexadecimal") )
{
// Set the new type and copy the old string to the new
lstrcat(szNewValue,L"00");
lstrcpy(szNewValue + VSA_OFFSET_NEW, pAttrValue + VSA_OFFSET);
}
// Error
else
{
_ASSERT(FALSE);
}
// Return the new string
NewString = szNewValue;
}
//////////////////////////////////////////////////////////////////////////////
// MigrateProxyServers
//////////////////////////////////////////////////////////////////////////////
void CMigrateMdb::MigrateProxyServers()
{
const long DEFAULT_PRIORITY = 1;
const long DEFAULT_WEIGHT = 50;
// If there isn't any servers.
if ( m_GlobalData.m_pRadiusServers->IsEmpty() )
{
return;
}
CProxyServerGroupCollection& ServerCollection
= CProxyServerGroupCollection::Instance();
// Do a loop on the RadiusServers sorted by server group
_bstr_t CurrentGroupName;
CProxyServersGroupHelper* pCurrentServerGroup = NULL; //avoid warning
// CurrentGroupName will never match a name received therefore
// pCurrentServerGroup will always be initialized before being used
HRESULT hr;
do
{
_bstr_t GroupName = m_GlobalData.m_pRadiusServers->GetGroupName();
if ( CurrentGroupName != GroupName )
{
CProxyServersGroupHelper ServerGroup(m_GlobalData);
CurrentGroupName = GroupName;
ServerGroup.SetName(GroupName);
// Add a server to the collection
pCurrentServerGroup = ServerCollection.Add(ServerGroup);
}
if ( !pCurrentServerGroup )
{
_com_issue_error(E_FAIL);
}
CProxyServerHelper Server(m_GlobalData);
_bstr_t ServerName = m_GlobalData.m_pRadiusServers->
GetProxyServerName();
Server.SetAddress(ServerName);
Server.SetAuthenticationPort(
m_GlobalData.m_pRadiusServers->GetAuthenticationPortNumber()
);
Server.SetAccountingPort(
m_GlobalData.m_pRadiusServers->GetAccountingPortNumber()
);
_bstr_t Secret = m_GlobalData.m_pRadiusServers->GetSharedSecret();
Server.SetAuthenticationSecret(Secret);
Server.SetPriority(DEFAULT_PRIORITY);
Server.SetWeight(DEFAULT_WEIGHT);
pCurrentServerGroup->Add(Server); // cannot be NULL pointer
hr = m_GlobalData.m_pRadiusServers->GetNext();
}
while (hr == S_OK);
// persist everything in the database
ServerCollection.Persist();
_com_util::CheckError(hr);
}
//////////////////////////////////////////////////////////////////////////////
// NewMigrateClients
//////////////////////////////////////////////////////////////////////////////
void CMigrateMdb::NewMigrateClients()
{
// If there isn't any client, return
if ( m_GlobalData.m_pClients->IsEmpty() )
{
return;
}
// for each client in the client table, add it (blindly) to the dest table
// i.e. walkpath to find the clients container
// create the properties for that containes (clients).
const WCHAR ClientContainerPath[] =
L"Root\0"
L"Microsoft Internet Authentication Service\0"
L"Protocols\0"
L"Microsoft Radius Protocol\0"
L"Clients\0";
LONG ClientContainerIdentity;
m_GlobalData.m_pObjects->WalkPath(
ClientContainerPath,
ClientContainerIdentity
);
HRESULT hr;
do
{
_bstr_t ClientName = m_GlobalData.m_pClients->GetHostName();
_bstr_t ClientSecret = m_GlobalData.m_pClients->GetSecret();
LONG ClientIdentity;
m_GlobalData.m_pObjects->InsertObject(
ClientName,
ClientContainerIdentity,
ClientIdentity
);
// Now insert the properties:
// IP Address
_bstr_t PropertyName = L"IP Address";
m_GlobalData.m_pProperties->InsertProperty(
ClientIdentity,
PropertyName,
VT_BSTR,
ClientName
);
// NAS Manufacturer
PropertyName = L"NAS Manufacturer";
_bstr_t StrValZero = L"0"; // RADIUS Standard
m_GlobalData.m_pProperties->InsertProperty(
ClientIdentity,
PropertyName,
VT_I4,
StrValZero
);
// Require Signature
PropertyName = L"Require Signature";
m_GlobalData.m_pProperties->InsertProperty(
ClientIdentity,
PropertyName,
VT_BOOL,
StrValZero
);
// Shared Secret
PropertyName = L"Shared Secret";
m_GlobalData.m_pProperties->InsertProperty(
ClientIdentity,
PropertyName,
VT_BSTR,
ClientSecret
);
hr = m_GlobalData.m_pClients->GetNext();
}
while ( hr == S_OK );
_com_util::CheckError(hr);
}
//////////////////////////////////////////////////////////////////////////////
// ConvertAttribute
//////////////////////////////////////////////////////////////////////////////
void CMigrateMdb::ConvertAttribute(
const _bstr_t& Value,
LONG Syntax,
LONG& Type,
bstr_t& StrVal
)
{
const size_t SIZE_LONG_MAX = 14;
switch (Syntax)
{
case IAS_SYNTAX_OCTETSTRING:
{
// abinary => OctetString
Type = VT_BSTR;
StrVal = Value;
break;
}
case IAS_SYNTAX_STRING:
case IAS_SYNTAX_UTCTIME:
case IAS_SYNTAX_PROVIDERSPECIFIC:
{
Type = VT_BSTR;
StrVal = Value;
break;
}
case IAS_SYNTAX_INETADDR:
{
unsigned long ulValue = ias_inet_addr(Value);
_ASSERT( ulValue != 0xffffffff );
Type = VT_I4;
WCHAR TempString[SIZE_LONG_MAX];
StrVal = _ultow(ulValue, TempString, 10);
break;
}
case IAS_SYNTAX_BOOLEAN:
{
LONG lValue = _wtol(Value);
Type = VT_BOOL;
StrVal = lValue? L"-1":L"0";
break;
}
case IAS_SYNTAX_INTEGER:
case IAS_SYNTAX_UNSIGNEDINTEGER:
case IAS_SYNTAX_ENUMERATOR:
{
Type = VT_I4;
StrVal = Value;
break;
}
default:
{
_com_issue_error(E_INVALIDARG);
}
}
}
//////////////////////////////////////////////////////////////////////////////
// MigrateAttribute
//////////////////////////////////////////////////////////////////////////////
void CMigrateMdb::MigrateAttribute(
const _bstr_t& Attribute,
LONG AttributeNumber,
const _bstr_t& AttributeValueName,
const _bstr_t& StringValue,
LONG RASProfileIdentity
)
{
// Note: Order might not be needed if the previous DB is always sorted
const size_t SIZE_LONG_MAX = 14;
_bstr_t LDAPName, StrVal;
LONG Syntax, Type; // Type: VT_BSTR, VT_I4, VT_BOOL
BOOL IsMultiValued;
HRESULT hr = m_GlobalData.m_pAttributes->GetAttribute(
AttributeNumber,
LDAPName,
Syntax,
IsMultiValued
);
if ( FAILED(hr) )
{
// Attribute unknown in the new dictionary
// that should never happen
return;
}
const LONG VSA = 26; //Vendor-Specific-Attribute
if ( StringValue.length() && ( AttributeNumber != VSA) )
{
// ordinary attribute, not an enumerator
ConvertAttribute(
StringValue,
Syntax,
Type,
StrVal
);
if ( IsMultiValued )
{
// If the attribute is multivalued then we need to add the value
// Otherwise we just update the attribute value
m_GlobalData.m_pProperties->InsertProperty(
RASProfileIdentity,
LDAPName,
Type,
StrVal
);
}
else
{
m_GlobalData.m_pProperties->UpdateProperty(
RASProfileIdentity,
LDAPName,
Type,
StrVal
);
}
}
else if ( StringValue.length() && ( AttributeNumber == VSA) )
{
// VSA Attribute (convert...)
if ( !AttributeValueName )
{
_com_issue_error(E_INVALIDARG);
}
ConvertVSA(AttributeValueName, StringValue, StrVal);
Type = VT_BSTR;
m_GlobalData.m_pProperties->InsertProperty(
RASProfileIdentity,
LDAPName,
Type,
StrVal
);
}
else if ( !StringValue.length() )
{
// Multivalued attribute.
Type = VT_I4;
// Get the number associated with it from the RadiusAttributeValues
// table
LONG Number = m_GlobalData.m_pRADIUSAttributeValues->GetAttributeNumber
(
Attribute,
AttributeValueName
);
WCHAR TempString[SIZE_LONG_MAX ];
StrVal = _ltow(Number, TempString, 10);
// The attribute should be multivalued
_ASSERTE(IsMultiValued);
m_GlobalData.m_pProperties->InsertProperty(
RASProfileIdentity,
LDAPName,
Type,
StrVal
);
}
else
{
// other (unknown)
_com_issue_error(E_FAIL);
}
}
//////////////////////////////////////////////////////////////////////////////
// MigrateOtherProfile
//////////////////////////////////////////////////////////////////////////////
void CMigrateMdb::MigrateOtherProfile(
const _bstr_t& ProfileName,
LONG ProfileIdentity
)
{
_bstr_t Attribute, AttributeValueName, StringValue;
LONG Order, AttributeNumber;
// Now add the attributes from the NT4 file
HRESULT hr = m_GlobalData.m_pProfileAttributeList->GetAttribute(
ProfileName,
Attribute,
AttributeNumber,
AttributeValueName,
StringValue,
Order
);
LONG IndexAttribute = 1;
// For each attribute in the Profile Attribute List
// with szProfile = ProfileName
while ( SUCCEEDED(hr) )
{
// migrate it to the default RAS profile in IAS.mdb
MigrateAttribute(
Attribute,
AttributeNumber,
AttributeValueName,
StringValue,
ProfileIdentity
);
hr = m_GlobalData.m_pProfileAttributeList->GetAttribute(
ProfileName,
Attribute,
AttributeNumber,
AttributeValueName,
StringValue,
Order,
IndexAttribute
);
++IndexAttribute;
}
}
//////////////////////////////////////////////////////////////////////////////
// MigrateCorpProfile
//////////////////////////////////////////////////////////////////////////////
void CMigrateMdb::MigrateCorpProfile(
const _bstr_t& ProfileName,
const _bstr_t& Description
)
{
_bstr_t Attribute, AttributeValueName, StringValue;
LONG Order, AttributeNumber;
// empty the default profiles attributes
const WCHAR RASProfilePath[] =
L"Root\0"
L"Microsoft Internet Authentication Service\0"
L"RadiusProfiles\0";
LONG RASProfileIdentity;
m_GlobalData.m_pObjects->WalkPath(RASProfilePath, RASProfileIdentity);
// Now get the first profile: that's the default (localized) RAS profile
_bstr_t DefaultProfileName;
LONG DefaultProfileIdentity;
m_GlobalData.m_pObjects->GetObject(
DefaultProfileName,
DefaultProfileIdentity,
RASProfileIdentity
);
// Clean the default attributes
m_GlobalData.m_pProperties->DeleteProperty(
DefaultProfileIdentity,
L"msRADIUSServiceType"
);
m_GlobalData.m_pProperties->DeleteProperty(
DefaultProfileIdentity,
L"msRADIUSFramedProtocol"
);
// Now add the attributes from the NT4 file
HRESULT hr = m_GlobalData.m_pProfileAttributeList->GetAttribute(
ProfileName,
Attribute,
AttributeNumber,
AttributeValueName,
StringValue,
Order
);
LONG IndexAttribute = 1;
// For each attribute in the Profile Attribute List
// with szProfile = ProfileName
while ( SUCCEEDED(hr) )
{
// migrate it to the default RAS profile in IAS.mdb
MigrateAttribute(
Attribute,
AttributeNumber,
AttributeValueName,
StringValue,
DefaultProfileIdentity
);
hr = m_GlobalData.m_pProfileAttributeList->GetAttribute(
ProfileName,
Attribute,
AttributeNumber,
AttributeValueName,
StringValue,
Order,
IndexAttribute
);
++IndexAttribute;
}
// now not matter what, if Description == ODBC,
// Then the policy should have a condition to never match.
// (update msNPConstraint
const _bstr_t BadProvider = L"ODBC";
if ( Description == BadProvider ) //safe compare
{
// Get the Policy container
const WCHAR RASPolicyPath[] =
L"Root\0"
L"Microsoft Internet Authentication Service\0"
L"NetworkPolicy\0";
// Get its (unique) child
LONG RASPolicyIdentity;
m_GlobalData.m_pObjects->WalkPath(RASPolicyPath, RASPolicyIdentity);
// Now get the first policy: that's the default (localized) RAS policy
_bstr_t DefaultPolicyName;
LONG DefaultPolicyIdentity;
m_GlobalData.m_pObjects->GetObject(
DefaultPolicyName,
DefaultPolicyIdentity,
RASPolicyIdentity
);
// delete the msNPConstraint (s)
const _bstr_t Constraint = L"msNPConstraint";
m_GlobalData.m_pProperties->DeleteProperty(
DefaultPolicyIdentity,
Constraint
);
// add a TIMEOFDAY that never matches
const _bstr_t DumbTime = L"TIMEOFDAY(\"\")";
m_GlobalData.m_pProperties->InsertProperty(
RASPolicyIdentity,
Constraint,
VT_BSTR,
DumbTime
);
}
}
//////////////////////////////////////////////////////////////////////////////
// NewMigrateProfiles
//////////////////////////////////////////////////////////////////////////////
void CMigrateMdb::NewMigrateProfiles()
{
const LONG AUTH_PROVIDER_WINDOWS = 1;
const LONG AUTH_PROVIDER_RADIUS_PROXY = 2;
const LONG ACCT_PROVIDER_RADIUS_PROXY = 2;
const _bstr_t RemoteRADIUSServers = L"Remote RADIUS Servers";
const _bstr_t MCIS = L"MCIS";
const _bstr_t MCISv2 = L"MCIS version 2.0";
const _bstr_t ODBC = L"ODBC";
const _bstr_t WindowsNT = L"Windows NT";
const _bstr_t MatchAll = L"TIMEOFDAY(\"0 00:00-24:00; 1 00:00"
L"-24:00; 2 00:00-24:00; 3 00:00-24:00; 4 00:00-24:00; 5 00:"
L"00-24:00; 6 00:00-24:00\")";
// Get the Default Provider's data
_bstr_t DPUserDefinedName, DPProfile;
VARIANT_BOOL DPForwardAccounting, DPSupressAccounting
, DPLogoutAccounting;
m_GlobalData.m_pDefaultProvider->GetDefaultProvider(
DPUserDefinedName,
DPProfile,
DPForwardAccounting,
DPSupressAccounting,
DPLogoutAccounting
);
_bstr_t ProfileName = m_GlobalData.m_pProfiles->GetProfileName();
// Do the NT4 CORP migration first if needed
if ( m_Utils.IsNT4Corp() )
{
// This is NT4 CORP. migrate the default profile into
// the default policy/profile (not the proxy default)
_bstr_t Description = m_GlobalData.m_pProviders->
GetProviderDescription(DPUserDefinedName);
MigrateCorpProfile(ProfileName, Description);
// stop here
return;
}
// Now that is not a NT4 CORP migration
// Delete the default Proxy Policy / profile
const WCHAR ProxyPoliciesPath[] =
L"Root\0"
L"Microsoft Internet Authentication Service\0"
L"Proxy Policies\0";
LONG ProxyPolicyIdentity;
m_GlobalData.m_pObjects->WalkPath(ProxyPoliciesPath, ProxyPolicyIdentity);
// Now get the first profile: that's the default (localized) RAS policy
_bstr_t DefaultPolicyName;
LONG DefaultPolicyIdentity;
m_GlobalData.m_pObjects->GetObject(
DefaultPolicyName,
DefaultPolicyIdentity,
ProxyPolicyIdentity
);
m_GlobalData.m_pObjects->DeleteObject(DefaultPolicyIdentity);
// From now on the default proxy policy / profile is deleted
// Now empty the default RAS profiles attributes
const WCHAR RASProfilePath[] =
L"Root\0"
L"Microsoft Internet Authentication Service\0"
L"RadiusProfiles\0";
LONG RASProfileIdentity;
m_GlobalData.m_pObjects->WalkPath(RASProfilePath, RASProfileIdentity);
// Now get the first profile: that's the default (localized) RAS profile
_bstr_t DefaultProfileName;
LONG DefaultProfileIdentity;
m_GlobalData.m_pObjects->GetObject(
DefaultProfileName,
DefaultProfileIdentity,
RASProfileIdentity
);
// Clean the default attributes
m_GlobalData.m_pProperties->DeleteProperty(
DefaultProfileIdentity,
L"msRADIUSServiceType"
);
m_GlobalData.m_pProperties->DeleteProperty(
DefaultProfileIdentity,
L"msRADIUSFramedProtocol"
);
// from now on the default RAS profile has its default attributes (the one
// in the Advanced tab in the UI) deleted.
HRESULT hr;
LONG Sequence = 1;
// Get the list of the profiles
do
{
LONG RealmIndex = 0;
ProfileName = m_GlobalData.m_pProfiles->GetProfileName();
// Note: hr should be set only by GetRealmIndex
do
{
// Get the realms associated with that profile
CPolicy TempPolicy;
hr = m_GlobalData.m_pRealms->GetRealmIndex(ProfileName,RealmIndex);
if ( hr != S_OK )
{
// exit that internal do / while to get the next profile
break;
}
_bstr_t RealmName = m_GlobalData.m_pRealms->GetRealmName();
TempPolicy.SetmsNPAction(RealmName);
++RealmIndex;
// That will set the realm part of the profile based on the
// values in NT4 as well as the reg keys values
m_GlobalData.m_pRealms->SetRealmDetails(
TempPolicy,
m_Utils
);
_bstr_t UserDefinedName = m_GlobalData.m_pRealms
->GetUserDefinedName();
// Look up the provider in the providers table. Note: Assume
// the proxy servers (and groups) are already migrated.
_bstr_t ProviderDescription = m_GlobalData.m_pProviders
->GetProviderDescription(UserDefinedName);
// Set the sequence order
TempPolicy.SetmsNPSequence(Sequence);
// Now set the authentication provider
if ( ProviderDescription == RemoteRADIUSServers )
{
TempPolicy.SetmsAuthProviderType(
AUTH_PROVIDER_RADIUS_PROXY,
UserDefinedName
);
}
else if ( ( ProviderDescription == MCIS ) ||
( ProviderDescription == MCISv2 ) ||
( ProviderDescription == WindowsNT ) )
{
TempPolicy.SetmsAuthProviderType(AUTH_PROVIDER_WINDOWS);
}
else if ( ProviderDescription == ODBC )
{
// If ODBC is the authentication provider,
// then convert that realm into a policy that would never match.
// Authentication provider should be NT Domain.
TempPolicy.SetmsAuthProviderType(AUTH_PROVIDER_WINDOWS);
const _bstr_t MatchNothing = L"TIMEOFDAY(\"\")";
TempPolicy.SetmsNPConstraint(MatchNothing);
}
else
{
_com_issue_error(E_INVALIDARG);
}
// persist the policy
LONG ProfileIdentity = TempPolicy.Persist(m_GlobalData);
// migrate the profile associated with that policy
MigrateOtherProfile(ProfileName, ProfileIdentity);
++Sequence;
} while (hr == S_OK);
hr = m_GlobalData.m_pProfiles->GetNext();
} while ( hr == S_OK );
if ( DPUserDefinedName.length() )
{
// there is a default provider: a default policy needs to be created
// same logic as above (mostly)
CPolicy DefaultPolicy;
DefaultPolicy.SetmsNPAction(DPProfile);
_bstr_t ProviderDescription = m_GlobalData.m_pProviders
->GetProviderDescription(DPUserDefinedName);
if ( ProviderDescription == RemoteRADIUSServers )
{
DefaultPolicy.SetmsAuthProviderType(
AUTH_PROVIDER_RADIUS_PROXY,
DPUserDefinedName
);
DefaultPolicy.SetmsNPConstraint(MatchAll);
}
else if ( ( ProviderDescription == MCIS ) ||
( ProviderDescription == MCISv2 ) ||
( ProviderDescription == WindowsNT ) )
{
DefaultPolicy.SetmsNPConstraint(MatchAll);
DefaultPolicy.SetmsAuthProviderType(AUTH_PROVIDER_WINDOWS);
}
else if ( ProviderDescription == ODBC )
{
// If ODBC is the authentication provider,
// then convert that realm into a policy that would never match.
// Authentication provider should be NT Domain.
DefaultPolicy.SetmsAuthProviderType(AUTH_PROVIDER_WINDOWS);
const _bstr_t MatchNothing = L"TIMEOFDAY(\"\")";
DefaultPolicy.SetmsNPConstraint(MatchNothing);
}
else
{
_com_issue_error(E_INVALIDARG);
}
DefaultPolicy.SetmsNPSequence(Sequence);
if ( DPForwardAccounting )
{
DefaultPolicy.SetmsAcctProviderType(ACCT_PROVIDER_RADIUS_PROXY);
}
LONG ProfileIdentity = DefaultPolicy.Persist(m_GlobalData);
MigrateOtherProfile(DPProfile, ProfileIdentity);
}
// else no default provider: no default policy
}
//////////////////////////////////////////////////////////////////////////////
// NewMigrateAccounting
//////////////////////////////////////////////////////////////////////////////
void CMigrateMdb::NewMigrateAccounting()
{
const WCHAR AccountingPath[] =
L"Root\0"
L"Microsoft Internet Authentication Service\0"
L"RequestHandlers\0"
L"Microsoft Accounting\0";
LONG AccountingIdentity;
m_GlobalData.m_pObjects->WalkPath(AccountingPath, AccountingIdentity);
_bstr_t MaxLogSize = m_GlobalData.m_pServiceConfiguration->GetMaxLogSize();
_bstr_t LogFrequency = m_GlobalData.m_pServiceConfiguration->
GetLogFrequency();
_bstr_t PropertyName = L"New Log Frequency";
m_GlobalData.m_pProperties->UpdateProperty(
AccountingIdentity,
PropertyName,
VT_I4,
LogFrequency
);
PropertyName = L"New Log Size";
m_GlobalData.m_pProperties->UpdateProperty(
AccountingIdentity,
PropertyName,
VT_I4,
MaxLogSize
);
DWORD Value;
m_Utils.NewGetAuthSrvParameter(L"LogAuthentications", Value);
_bstr_t LogAuth;
Value ? LogAuth = L"-1": LogAuth = L"0";
PropertyName = L"Log Authentication Packets";
m_GlobalData.m_pProperties->UpdateProperty(
AccountingIdentity,
PropertyName,
VT_BOOL,
LogAuth
);
m_Utils.NewGetAuthSrvParameter(L"LogAccounting", Value);
_bstr_t LogAcct;
Value ? LogAcct = L"-1": LogAcct = L"0";
PropertyName = L"Log Accounting Packets";
m_GlobalData.m_pProperties->UpdateProperty(
AccountingIdentity,
PropertyName,
VT_BOOL,
LogAcct
);
_bstr_t FormatIAS1 = L"0";
PropertyName = L"Log Format";
m_GlobalData.m_pProperties->UpdateProperty(
AccountingIdentity,
PropertyName,
VT_I4,
FormatIAS1
);
}
//////////////////////////////////////////////////////////////////////////////
// NewMigrateEventLog
//////////////////////////////////////////////////////////////////////////////
void CMigrateMdb::NewMigrateEventLog()
{
const WCHAR EventLogPath[] =
L"Root\0"
L"Microsoft Internet Authentication Service\0"
L"Auditors\0"
L"Microsoft NT Event Log Auditor\0";
LONG EventLogIdentity;
m_GlobalData.m_pObjects->WalkPath(EventLogPath, EventLogIdentity);
DWORD Value;
m_Utils.NewGetAuthSrvParameter(L"LogData", Value);
_bstr_t LogData;
Value ? LogData = L"-1": LogData = L"0";
_bstr_t PropertyName = L"Log Verbose";
m_GlobalData.m_pProperties->UpdateProperty(
EventLogIdentity,
PropertyName,
VT_BOOL,
LogData
);
m_Utils.NewGetAuthSrvParameter(L"LogBogus", Value);
_bstr_t LogBogus;
Value ? LogBogus = L"-1": LogBogus = L"0";
PropertyName = L"Log Malformed Packets";
m_GlobalData.m_pProperties->UpdateProperty(
EventLogIdentity,
PropertyName,
VT_BOOL,
LogBogus
);
}
//////////////////////////////////////////////////////////////////////////////
// NewMigrateService
//////////////////////////////////////////////////////////////////////////////
void CMigrateMdb::NewMigrateService()
{
const LONG PORT_SIZE_MAX = 34;
const WCHAR ServicePath[] =
L"Root\0"
L"Microsoft Internet Authentication Service\0"
L"Protocols\0"
L"Microsoft Radius Protocol\0";
LONG ServiceIdentity;
m_GlobalData.m_pObjects->WalkPath(ServicePath, ServiceIdentity);
DWORD Value;
m_Utils.NewGetAuthSrvParameter(L"RadiusPort", Value);
WCHAR TempString[PORT_SIZE_MAX];
_bstr_t RadiusPort = _ultow(Value, TempString, 10);
_bstr_t PropertyName = L"Authentication Port";
m_GlobalData.m_pProperties->UpdateProperty(
ServiceIdentity,
PropertyName,
VT_BSTR,
RadiusPort
);
m_Utils.NewGetAuthSrvParameter(L"AcctPort", Value);
_bstr_t AcctPort = _ltow(Value, TempString, 10);
PropertyName = L"Accounting Port";
m_GlobalData.m_pProperties->UpdateProperty(
ServiceIdentity,
PropertyName,
VT_BSTR,
AcctPort
);
}
//////////////////////////////////////////////////////////////////////////////
// NewMigrate
//////////////////////////////////////////////////////////////////////////////
void CMigrateMdb::NewMigrate()
{
NewMigrateClients();
if ( !m_Utils.IsNT4Corp() ) // it's either Win2k or NT4 ISP
{
// the proxy servers must be migrated before the policies and
// profiles
MigrateProxyServers();
}
NewMigrateProfiles();
NewMigrateAccounting();
NewMigrateEventLog();
NewMigrateService();
/////////////////////////////
// Migrate the Registry Keys
/////////////////////////////
CMigrateRegistry MigrateRegistry(m_Utils);
MigrateRegistry.MigrateProviders();
//////////////////////////////////////////////////////
// Update the MSChap Authentication types (password)
//////////////////////////////////////////////////////
CUpdateMSCHAP UpdateMSCHAP(m_GlobalData);
UpdateMSCHAP.Execute();
}