Source code of Windows XP (NT5)
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.

198 lines
4.7 KiB

  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 1998, Microsoft Corp. All rights reserved.
  4. //
  5. // FILE
  6. //
  7. // samutil.cpp
  8. //
  9. // SYNOPSIS
  10. //
  11. // Defines the functions IASEncryptAttribute & IASProcessFailure.
  12. //
  13. // MODIFICATION HISTORY
  14. //
  15. // 08/24/1998 Original version.
  16. // 02/13/1999 Check for VSAs in IASEncryptAttribute.
  17. // 03/23/1999 Added IASStoreFQUserName.
  18. // 05/04/1999 New reason codes.
  19. // 05/11/1999 Fix RADIUS encryption.
  20. // 07/09/1999 IAS_ATTRIBUTE_FULLY_QUALIFIED_USER_NAME is internal.
  21. // 10/21/1999 Add support for IAS_NO_CLEARTEXT_PASSWORD.
  22. //
  23. ///////////////////////////////////////////////////////////////////////////////
  24. #include <ias.h>
  25. #include <lm.h>
  26. #include <ntdsapi.h>
  27. #include <sdoias.h>
  28. #include <samutil.h>
  29. HRESULT
  30. WINAPI
  31. IASStoreFQUserName(
  32. IAttributesRaw* request,
  33. DS_NAME_FORMAT format,
  34. PCWSTR fqdn
  35. ) throw ()
  36. {
  37. // Check the arguments.
  38. if (!request || !fqdn) { return E_POINTER; }
  39. // Convert DN's to canonical names.
  40. PDS_NAME_RESULTW result = NULL;
  41. if (format == DS_FQDN_1779_NAME)
  42. {
  43. DWORD err = DsCrackNamesW(
  44. NULL,
  45. DS_NAME_FLAG_SYNTACTICAL_ONLY,
  46. format,
  47. DS_CANONICAL_NAME,
  48. 1,
  49. &fqdn,
  50. &result
  51. );
  52. if (err == NO_ERROR &&
  53. result->cItems == 1 &&
  54. result->rItems[0].status == DS_NAME_NO_ERROR)
  55. {
  56. fqdn = result->rItems[0].pName;
  57. }
  58. }
  59. HRESULT hr;
  60. // Allocate an attribute.
  61. PIASATTRIBUTE attr;
  62. if (IASAttributeAlloc(1, &attr) == NO_ERROR)
  63. {
  64. // Allocate memory for the string.
  65. ULONG nbyte = (wcslen(fqdn) + 1) * sizeof(WCHAR);
  66. attr->Value.String.pszWide = (PWSTR)CoTaskMemAlloc(nbyte);
  67. if (attr->Value.String.pszWide)
  68. {
  69. // Copy in the value.
  70. memcpy(attr->Value.String.pszWide, fqdn, nbyte);
  71. attr->Value.String.pszAnsi = NULL;
  72. // Set the other fields of the struct.
  73. attr->Value.itType = IASTYPE_STRING;
  74. attr->dwId = IAS_ATTRIBUTE_FULLY_QUALIFIED_USER_NAME;
  75. // Remove any existing attributes of this type.
  76. request->RemoveAttributesByType(1, &attr->dwId);
  77. // Store the attribute in the request.
  78. ATTRIBUTEPOSITION pos = { 0, attr };
  79. hr = request->AddAttributes(1, &pos);
  80. }
  81. else
  82. {
  83. // CoTaskMemAlloc failed.
  84. hr = E_OUTOFMEMORY;
  85. }
  86. // Free up the attribute.
  87. IASAttributeRelease(attr);
  88. }
  89. else
  90. {
  91. // IASAttributeAlloc failed.
  92. hr = E_OUTOFMEMORY;
  93. }
  94. DsFreeNameResult(result);
  95. return hr;
  96. }
  97. VOID
  98. WINAPI
  99. IASEncryptBuffer(
  100. IAttributesRaw* request,
  101. BOOL salted,
  102. PBYTE buf,
  103. ULONG buflen
  104. ) throw ()
  105. {
  106. /////////
  107. // Do we have the attributes required for encryption.
  108. /////////
  109. PIASATTRIBUTE secret, header;
  110. secret = IASPeekAttribute(
  111. request,
  112. IAS_ATTRIBUTE_SHARED_SECRET,
  113. IASTYPE_OCTET_STRING
  114. );
  115. header = IASPeekAttribute(
  116. request,
  117. IAS_ATTRIBUTE_CLIENT_PACKET_HEADER,
  118. IASTYPE_OCTET_STRING
  119. );
  120. if (secret && header)
  121. {
  122. IASRadiusCrypt(
  123. TRUE,
  124. salted,
  125. secret->Value.OctetString.lpValue,
  126. secret->Value.OctetString.dwLength,
  127. header->Value.OctetString.lpValue + 4,
  128. buf,
  129. buflen
  130. );
  131. }
  132. }
  133. IASREQUESTSTATUS
  134. WINAPI
  135. IASProcessFailure(
  136. IRequest* pRequest,
  137. HRESULT hrError
  138. )
  139. {
  140. if (pRequest == NULL) { return IAS_REQUEST_STATUS_ABORT; }
  141. if (hrError == S_OK) { hrError = E_FAIL; }
  142. IASRESPONSE response;
  143. IASREQUESTSTATUS status;
  144. switch (hrError)
  145. {
  146. // Errors which cause a reject.
  147. case IAS_NO_SUCH_DOMAIN:
  148. case IAS_NO_SUCH_USER:
  149. case IAS_AUTH_FAILURE:
  150. case IAS_CHANGE_PASSWORD_FAILURE:
  151. case IAS_UNSUPPORTED_AUTH_TYPE:
  152. case IAS_NO_CLEARTEXT_PASSWORD:
  153. case IAS_LM_NOT_ALLOWED:
  154. case IAS_LOCAL_USERS_ONLY:
  155. case IAS_PASSWORD_MUST_CHANGE:
  156. case IAS_ACCOUNT_DISABLED:
  157. case IAS_ACCOUNT_EXPIRED:
  158. case IAS_ACCOUNT_LOCKED_OUT:
  159. case IAS_INVALID_LOGON_HOURS:
  160. case IAS_ACCOUNT_RESTRICTION:
  161. {
  162. response = IAS_RESPONSE_ACCESS_REJECT;
  163. status = IAS_REQUEST_STATUS_HANDLED;
  164. break;
  165. }
  166. // Everything else we discard.
  167. default:
  168. {
  169. response = IAS_RESPONSE_DISCARD_PACKET;
  170. status = IAS_REQUEST_STATUS_ABORT;
  171. }
  172. }
  173. HRESULT hr = pRequest->SetResponse(response, hrError);
  174. return (FAILED(hr)) ? IAS_REQUEST_STATUS_ABORT : status;
  175. }