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.
218 lines
5.1 KiB
218 lines
5.1 KiB
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Copyright (c) Microsoft Corporation
|
|
//
|
|
// SYNOPSIS
|
|
//
|
|
// Defines the class RadiusExtensionPoint
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
#include "Precompiled.h"
|
|
#include "ias.h"
|
|
#include "ExtensionPoint.h"
|
|
#include "Extension.h"
|
|
#include <new>
|
|
|
|
|
|
RadiusExtensionPoint::RadiusExtensionPoint() throw ()
|
|
: name(L""),
|
|
begin(0),
|
|
end(0)
|
|
{
|
|
}
|
|
|
|
|
|
RadiusExtensionPoint::~RadiusExtensionPoint() throw ()
|
|
{
|
|
delete[] begin;
|
|
}
|
|
|
|
|
|
DWORD RadiusExtensionPoint::Load(RADIUS_EXTENSION_POINT whichDlls) throw ()
|
|
{
|
|
DWORD status = NO_ERROR;
|
|
HKEY key = 0;
|
|
bool ignoreFindNotFound = true;
|
|
|
|
do
|
|
{
|
|
name = (whichDlls == repAuthentication) ? AUTHSRV_EXTENSIONS_VALUE_W
|
|
: AUTHSRV_AUTHORIZATION_VALUE_W;
|
|
|
|
IASTracePrintf("Loading %S", name);
|
|
|
|
// Open the registry key.
|
|
status = RegOpenKeyW(
|
|
HKEY_LOCAL_MACHINE,
|
|
AUTHSRV_PARAMETERS_KEY_W,
|
|
&key
|
|
);
|
|
if (status != NO_ERROR)
|
|
{
|
|
if (status == ERROR_FILE_NOT_FOUND)
|
|
{
|
|
IASTracePrintf(
|
|
"%S doesn't exist; no extensions loaded.",
|
|
AUTHSRV_PARAMETERS_KEY_W
|
|
);
|
|
}
|
|
else
|
|
{
|
|
IASTracePrintf(
|
|
"RegOpenKeyW for %S failed with error %ld.",
|
|
AUTHSRV_PARAMETERS_KEY_W,
|
|
status
|
|
);
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
// Allocate a buffer to hold the value.
|
|
DWORD type, length;
|
|
status = RegQueryValueExW(
|
|
key,
|
|
name,
|
|
0,
|
|
&type,
|
|
0,
|
|
&length
|
|
);
|
|
if (status != NO_ERROR)
|
|
{
|
|
IASTracePrintf(
|
|
"RegQueryValueExW for %S failed with error %ld.",
|
|
name,
|
|
status
|
|
);
|
|
break;
|
|
}
|
|
BYTE* data = static_cast<BYTE*>(_alloca(length));
|
|
|
|
// Read the registry value.
|
|
status = RegQueryValueExW(
|
|
key,
|
|
name,
|
|
0,
|
|
&type,
|
|
data,
|
|
&length
|
|
);
|
|
if (status != NO_ERROR)
|
|
{
|
|
IASTracePrintf(
|
|
"RegQueryValueExW for %S failed with error %ld.",
|
|
name,
|
|
status
|
|
);
|
|
break;
|
|
}
|
|
|
|
// Make sure it's the right type.
|
|
if (type != REG_MULTI_SZ)
|
|
{
|
|
IASTracePrintf(
|
|
"%S registry value is not of type REG_MULTI_SZ.",
|
|
name
|
|
);
|
|
status = ERROR_INVALID_DATA;
|
|
break;
|
|
}
|
|
|
|
// Count the number of strings.
|
|
size_t numExtensions = 0;
|
|
const wchar_t* path;
|
|
for (path = reinterpret_cast<const wchar_t*>(data);
|
|
*path != L'\0';
|
|
path += (wcslen(path) + 1))
|
|
{
|
|
if (!IsNT4Only(path))
|
|
{
|
|
++numExtensions;
|
|
}
|
|
}
|
|
|
|
// If there are no extensions, then we're done.
|
|
if (numExtensions == 0)
|
|
{
|
|
IASTraceString("No extensions registered.");
|
|
break;
|
|
}
|
|
|
|
// Allocate memory to hold the extensions.
|
|
begin = new (std::nothrow) RadiusExtension[numExtensions];
|
|
if (begin == 0)
|
|
{
|
|
status = ERROR_NOT_ENOUGH_MEMORY;
|
|
break;
|
|
}
|
|
|
|
// Load the DLL's.
|
|
end = begin;
|
|
for (path = reinterpret_cast<const wchar_t*>(data);
|
|
*path != L'\0';
|
|
path += (wcslen(path) + 1))
|
|
{
|
|
if (!IsNT4Only(path))
|
|
{
|
|
status = end->Load(path);
|
|
if (status != NO_ERROR)
|
|
{
|
|
ignoreFindNotFound = false;
|
|
// Clear any partial result.
|
|
Clear();
|
|
break;
|
|
}
|
|
++end;
|
|
}
|
|
}
|
|
} while (false);
|
|
|
|
// Close the registry.
|
|
if (key != 0)
|
|
{
|
|
RegCloseKey(key);
|
|
}
|
|
|
|
// If no extensions are registered, then it's not really an error.
|
|
if (ignoreFindNotFound && (status == ERROR_FILE_NOT_FOUND))
|
|
{
|
|
status = NO_ERROR;
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
|
|
void RadiusExtensionPoint::Process(
|
|
RADIUS_EXTENSION_CONTROL_BLOCK* ecb
|
|
) const throw ()
|
|
{
|
|
IASTracePrintf("Invoking %S", name);
|
|
|
|
for (const RadiusExtension* i = begin; i != end; ++i)
|
|
{
|
|
DWORD result = i->Process(ecb);
|
|
if (result != NO_ERROR)
|
|
{
|
|
ecb->SetResponseType(ecb, rcDiscard);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void RadiusExtensionPoint::Clear() throw ()
|
|
{
|
|
delete[] begin;
|
|
|
|
begin = 0;
|
|
end = 0;
|
|
}
|
|
|
|
|
|
bool RadiusExtensionPoint::IsNT4Only(const wchar_t* path) throw ()
|
|
{
|
|
// Is this the authsam extension?
|
|
return _wcsicmp(ExtractFileNameFromPath(path), L"AUTHSAM.DLL") == 0;
|
|
}
|