Leaked source code of windows server 2003
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

  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) Microsoft Corporation
  4. //
  5. // SYNOPSIS
  6. //
  7. // Defines the class RadiusExtensionPoint
  8. //
  9. ///////////////////////////////////////////////////////////////////////////////
  10. #include "Precompiled.h"
  11. #include "ias.h"
  12. #include "ExtensionPoint.h"
  13. #include "Extension.h"
  14. #include <new>
  15. RadiusExtensionPoint::RadiusExtensionPoint() throw ()
  16. : name(L""),
  17. begin(0),
  18. end(0)
  19. {
  20. }
  21. RadiusExtensionPoint::~RadiusExtensionPoint() throw ()
  22. {
  23. delete[] begin;
  24. }
  25. DWORD RadiusExtensionPoint::Load(RADIUS_EXTENSION_POINT whichDlls) throw ()
  26. {
  27. DWORD status = NO_ERROR;
  28. HKEY key = 0;
  29. bool ignoreFindNotFound = true;
  30. do
  31. {
  32. name = (whichDlls == repAuthentication) ? AUTHSRV_EXTENSIONS_VALUE_W
  33. : AUTHSRV_AUTHORIZATION_VALUE_W;
  34. IASTracePrintf("Loading %S", name);
  35. // Open the registry key.
  36. status = RegOpenKeyW(
  37. HKEY_LOCAL_MACHINE,
  38. AUTHSRV_PARAMETERS_KEY_W,
  39. &key
  40. );
  41. if (status != NO_ERROR)
  42. {
  43. if (status == ERROR_FILE_NOT_FOUND)
  44. {
  45. IASTracePrintf(
  46. "%S doesn't exist; no extensions loaded.",
  47. AUTHSRV_PARAMETERS_KEY_W
  48. );
  49. }
  50. else
  51. {
  52. IASTracePrintf(
  53. "RegOpenKeyW for %S failed with error %ld.",
  54. AUTHSRV_PARAMETERS_KEY_W,
  55. status
  56. );
  57. }
  58. break;
  59. }
  60. // Allocate a buffer to hold the value.
  61. DWORD type, length;
  62. status = RegQueryValueExW(
  63. key,
  64. name,
  65. 0,
  66. &type,
  67. 0,
  68. &length
  69. );
  70. if (status != NO_ERROR)
  71. {
  72. IASTracePrintf(
  73. "RegQueryValueExW for %S failed with error %ld.",
  74. name,
  75. status
  76. );
  77. break;
  78. }
  79. BYTE* data = static_cast<BYTE*>(_alloca(length));
  80. // Read the registry value.
  81. status = RegQueryValueExW(
  82. key,
  83. name,
  84. 0,
  85. &type,
  86. data,
  87. &length
  88. );
  89. if (status != NO_ERROR)
  90. {
  91. IASTracePrintf(
  92. "RegQueryValueExW for %S failed with error %ld.",
  93. name,
  94. status
  95. );
  96. break;
  97. }
  98. // Make sure it's the right type.
  99. if (type != REG_MULTI_SZ)
  100. {
  101. IASTracePrintf(
  102. "%S registry value is not of type REG_MULTI_SZ.",
  103. name
  104. );
  105. status = ERROR_INVALID_DATA;
  106. break;
  107. }
  108. // Count the number of strings.
  109. size_t numExtensions = 0;
  110. const wchar_t* path;
  111. for (path = reinterpret_cast<const wchar_t*>(data);
  112. *path != L'\0';
  113. path += (wcslen(path) + 1))
  114. {
  115. if (!IsNT4Only(path))
  116. {
  117. ++numExtensions;
  118. }
  119. }
  120. // If there are no extensions, then we're done.
  121. if (numExtensions == 0)
  122. {
  123. IASTraceString("No extensions registered.");
  124. break;
  125. }
  126. // Allocate memory to hold the extensions.
  127. begin = new (std::nothrow) RadiusExtension[numExtensions];
  128. if (begin == 0)
  129. {
  130. status = ERROR_NOT_ENOUGH_MEMORY;
  131. break;
  132. }
  133. // Load the DLL's.
  134. end = begin;
  135. for (path = reinterpret_cast<const wchar_t*>(data);
  136. *path != L'\0';
  137. path += (wcslen(path) + 1))
  138. {
  139. if (!IsNT4Only(path))
  140. {
  141. status = end->Load(path);
  142. if (status != NO_ERROR)
  143. {
  144. ignoreFindNotFound = false;
  145. // Clear any partial result.
  146. Clear();
  147. break;
  148. }
  149. ++end;
  150. }
  151. }
  152. } while (false);
  153. // Close the registry.
  154. if (key != 0)
  155. {
  156. RegCloseKey(key);
  157. }
  158. // If no extensions are registered, then it's not really an error.
  159. if (ignoreFindNotFound && (status == ERROR_FILE_NOT_FOUND))
  160. {
  161. status = NO_ERROR;
  162. }
  163. return status;
  164. }
  165. void RadiusExtensionPoint::Process(
  166. RADIUS_EXTENSION_CONTROL_BLOCK* ecb
  167. ) const throw ()
  168. {
  169. IASTracePrintf("Invoking %S", name);
  170. for (const RadiusExtension* i = begin; i != end; ++i)
  171. {
  172. DWORD result = i->Process(ecb);
  173. if (result != NO_ERROR)
  174. {
  175. ecb->SetResponseType(ecb, rcDiscard);
  176. }
  177. }
  178. }
  179. void RadiusExtensionPoint::Clear() throw ()
  180. {
  181. delete[] begin;
  182. begin = 0;
  183. end = 0;
  184. }
  185. bool RadiusExtensionPoint::IsNT4Only(const wchar_t* path) throw ()
  186. {
  187. // Is this the authsam extension?
  188. return _wcsicmp(ExtractFileNameFromPath(path), L"AUTHSAM.DLL") == 0;
  189. }