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.

223 lines
5.4 KiB

  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) Microsoft Corporation
  4. //
  5. // SYNOPSIS
  6. //
  7. // Defines the functions IASEncryptAttribute & IASProcessFailure.
  8. //
  9. ///////////////////////////////////////////////////////////////////////////////
  10. #include <ias.h>
  11. #include <lm.h>
  12. #include <ntdsapi.h>
  13. #include <sdoias.h>
  14. #include <samutil.h>
  15. HRESULT
  16. WINAPI
  17. IASStoreFQUserName(
  18. IAttributesRaw* request,
  19. DS_NAME_FORMAT format,
  20. PCWSTR fqdn
  21. ) throw ()
  22. {
  23. // Check the arguments.
  24. if (!request || !fqdn) { return E_POINTER; }
  25. // Convert DN's to canonical names.
  26. PDS_NAME_RESULTW result = NULL;
  27. if (format == DS_FQDN_1779_NAME)
  28. {
  29. DWORD err = DsCrackNamesW(
  30. NULL,
  31. DS_NAME_FLAG_SYNTACTICAL_ONLY,
  32. format,
  33. DS_CANONICAL_NAME,
  34. 1,
  35. &fqdn,
  36. &result
  37. );
  38. if (err == NO_ERROR &&
  39. result->cItems == 1 &&
  40. result->rItems[0].status == DS_NAME_NO_ERROR)
  41. {
  42. fqdn = result->rItems[0].pName;
  43. }
  44. }
  45. HRESULT hr;
  46. // Allocate an attribute.
  47. PIASATTRIBUTE attr;
  48. if (IASAttributeAlloc(1, &attr) == NO_ERROR)
  49. {
  50. // Allocate memory for the string.
  51. ULONG nbyte = (wcslen(fqdn) + 1) * sizeof(WCHAR);
  52. attr->Value.String.pszWide = (PWSTR)CoTaskMemAlloc(nbyte);
  53. if (attr->Value.String.pszWide)
  54. {
  55. // Copy in the value.
  56. memcpy(attr->Value.String.pszWide, fqdn, nbyte);
  57. attr->Value.String.pszAnsi = NULL;
  58. // Set the other fields of the struct.
  59. attr->Value.itType = IASTYPE_STRING;
  60. attr->dwId = IAS_ATTRIBUTE_FULLY_QUALIFIED_USER_NAME;
  61. // Remove any existing attributes of this type.
  62. request->RemoveAttributesByType(1, &attr->dwId);
  63. // Store the attribute in the request.
  64. ATTRIBUTEPOSITION pos = { 0, attr };
  65. hr = request->AddAttributes(1, &pos);
  66. }
  67. else
  68. {
  69. // CoTaskMemAlloc failed.
  70. hr = E_OUTOFMEMORY;
  71. }
  72. // Free up the attribute.
  73. IASAttributeRelease(attr);
  74. }
  75. else
  76. {
  77. // IASAttributeAlloc failed.
  78. hr = E_OUTOFMEMORY;
  79. }
  80. DsFreeNameResult(result);
  81. return hr;
  82. }
  83. VOID
  84. WINAPI
  85. IASEncryptBuffer(
  86. IAttributesRaw* request,
  87. BOOL salted,
  88. PBYTE buf,
  89. ULONG buflen
  90. ) throw ()
  91. {
  92. /////////
  93. // Do we have the attributes required for encryption.
  94. /////////
  95. PIASATTRIBUTE secret, header;
  96. secret = IASPeekAttribute(
  97. request,
  98. IAS_ATTRIBUTE_SHARED_SECRET,
  99. IASTYPE_OCTET_STRING
  100. );
  101. header = IASPeekAttribute(
  102. request,
  103. IAS_ATTRIBUTE_CLIENT_PACKET_HEADER,
  104. IASTYPE_OCTET_STRING
  105. );
  106. if (secret && header)
  107. {
  108. IASRadiusCrypt(
  109. TRUE,
  110. salted,
  111. secret->Value.OctetString.lpValue,
  112. secret->Value.OctetString.dwLength,
  113. header->Value.OctetString.lpValue + 4,
  114. buf,
  115. buflen
  116. );
  117. }
  118. }
  119. IASREQUESTSTATUS
  120. WINAPI
  121. IASProcessFailure(
  122. IRequest* pRequest,
  123. HRESULT hrError
  124. )
  125. {
  126. if (pRequest == NULL)
  127. {
  128. return IAS_REQUEST_STATUS_CONTINUE;
  129. }
  130. IASRESPONSE response;
  131. switch (hrError)
  132. {
  133. // Errors which cause a reject.
  134. case IAS_NO_SUCH_DOMAIN:
  135. case IAS_NO_SUCH_USER:
  136. case IAS_AUTH_FAILURE:
  137. case IAS_CHANGE_PASSWORD_FAILURE:
  138. case IAS_UNSUPPORTED_AUTH_TYPE:
  139. case IAS_NO_CLEARTEXT_PASSWORD:
  140. case IAS_LM_NOT_ALLOWED:
  141. case IAS_LOCAL_USERS_ONLY:
  142. case IAS_PASSWORD_MUST_CHANGE:
  143. case IAS_ACCOUNT_DISABLED:
  144. case IAS_ACCOUNT_EXPIRED:
  145. case IAS_ACCOUNT_LOCKED_OUT:
  146. case IAS_INVALID_LOGON_HOURS:
  147. case IAS_ACCOUNT_RESTRICTION:
  148. case IAS_EAP_NEGOTIATION_FAILED:
  149. {
  150. response = IAS_RESPONSE_ACCESS_REJECT;
  151. break;
  152. }
  153. case HRESULT_FROM_WIN32(ERROR_MORE_DATA):
  154. {
  155. hrError = IAS_MALFORMED_REQUEST;
  156. response = IAS_RESPONSE_DISCARD_PACKET;
  157. break;
  158. }
  159. // Everything else we discard.
  160. default:
  161. {
  162. // Make sure we report an appropriate reason code.
  163. if ((hrError == IAS_SUCCESS) || (hrError >= IAS_MAX_REASON_CODE))
  164. {
  165. hrError = IAS_INTERNAL_ERROR;
  166. }
  167. response = IAS_RESPONSE_DISCARD_PACKET;
  168. break;
  169. }
  170. }
  171. pRequest->SetResponse(response, hrError);
  172. return IAS_REQUEST_STATUS_CONTINUE;
  173. }
  174. SamExtractor::SamExtractor(const IASATTRIBUTE& identity)
  175. {
  176. if (identity.Value.itType != IASTYPE_STRING)
  177. {
  178. IASTL::issue_error(E_INVALIDARG);
  179. }
  180. // This is conceptually a const operation since we're not really changing
  181. // the value of the attribute.
  182. DWORD error = IASAttributeUnicodeAlloc(
  183. const_cast<IASATTRIBUTE*>(&identity)
  184. );
  185. if (error != NO_ERROR)
  186. {
  187. IASTL::issue_error(HRESULT_FROM_WIN32(error));
  188. }
  189. begin = identity.Value.String.pszWide;
  190. delim = wcschr(begin, L'\\');
  191. if (delim != 0)
  192. {
  193. *delim = L'\0';
  194. }
  195. }