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.

297 lines
6.9 KiB

  1. //+--------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1996 - 1999
  5. //
  6. // File: certlib.cpp
  7. //
  8. // Contents: Cert Server wrapper routines
  9. //
  10. //---------------------------------------------------------------------------
  11. #include <pch.cpp>
  12. #pragma hdrstop
  13. #include <ntlsa.h>
  14. #define wszCERTMAPIINFO L"CertServerMapiInfo"
  15. void
  16. InitLsaString(
  17. OUT LSA_UNICODE_STRING *plus,
  18. IN WCHAR const *pwsz,
  19. IN DWORD cb)
  20. {
  21. if (MAXDWORD == cb)
  22. {
  23. cb = lstrlenW(pwsz) * sizeof(WCHAR);
  24. }
  25. plus->Buffer = const_cast<WCHAR *>(pwsz);
  26. plus->Length = (USHORT) cb;
  27. plus->MaximumLength = plus->Length + sizeof(WCHAR);
  28. }
  29. HRESULT
  30. OpenPolicy(
  31. IN WCHAR const *pwszServerName,
  32. DWORD DesiredAccess,
  33. LSA_HANDLE *phPolicy)
  34. {
  35. HRESULT hr;
  36. LSA_OBJECT_ATTRIBUTES oa;
  37. LSA_UNICODE_STRING ServerString;
  38. LSA_UNICODE_STRING *plusServer;
  39. ZeroMemory(&oa, sizeof(oa));
  40. plusServer = NULL;
  41. if (NULL != pwszServerName)
  42. {
  43. InitLsaString(&ServerString, pwszServerName, MAXDWORD);
  44. plusServer = &ServerString;
  45. }
  46. hr = LsaOpenPolicy(plusServer, &oa, DesiredAccess, phPolicy);
  47. if (!NT_SUCCESS(hr))
  48. {
  49. _JumpError(hr, error, "LsaOpenPolicy");
  50. }
  51. error:
  52. return(hr);
  53. }
  54. HRESULT
  55. SaveString(
  56. IN WCHAR const *pwszIn,
  57. IN DWORD cwcIn,
  58. OUT WCHAR **ppwszOut)
  59. {
  60. HRESULT hr;
  61. WCHAR *pwsz;
  62. *ppwszOut = NULL;
  63. pwsz = (WCHAR *) LocalAlloc(LMEM_FIXED, (cwcIn + 1) * sizeof(WCHAR));
  64. if (NULL == pwsz)
  65. {
  66. hr = E_OUTOFMEMORY;
  67. _JumpError(hr, error, "LocalAlloc");
  68. }
  69. CopyMemory(pwsz, pwszIn, cwcIn * sizeof(WCHAR));
  70. pwsz[cwcIn] = L'\0';
  71. *ppwszOut = pwsz;
  72. hr = S_OK;
  73. error:
  74. return(hr);
  75. }
  76. //+--------------------------------------------------------------------------
  77. // myGetMapiInfo -- Retrieve a Name/Password from a global LSA secret
  78. //+--------------------------------------------------------------------------
  79. HRESULT
  80. myGetMapiInfo(
  81. OPTIONAL IN WCHAR const *pwszServerName,
  82. OUT WCHAR **ppwszProfileName,
  83. OUT WCHAR **ppwszLogonName,
  84. OUT WCHAR **ppwszPassword)
  85. {
  86. HRESULT hr;
  87. LSA_HANDLE hPolicy;
  88. UNICODE_STRING lusSecretKeyName;
  89. UNICODE_STRING *plusSecretData = NULL;
  90. DWORD cwc;
  91. DWORD cwcProfileName;
  92. DWORD cwcLogonName;
  93. DWORD cwcPassword;
  94. WCHAR const *pwsz;
  95. WCHAR *pwszProfileName = NULL;
  96. WCHAR *pwszLogonName = NULL;
  97. WCHAR *pwszPassword = NULL;
  98. if (NULL == ppwszProfileName ||
  99. NULL == ppwszLogonName ||
  100. NULL == ppwszPassword)
  101. {
  102. hr = E_POINTER;
  103. _JumpError(hr, error, "no data");
  104. }
  105. InitLsaString(&lusSecretKeyName, wszCERTMAPIINFO, MAXDWORD);
  106. hr = OpenPolicy(pwszServerName, POLICY_GET_PRIVATE_INFORMATION, &hPolicy);
  107. if (!NT_SUCCESS(hr))
  108. {
  109. _JumpError(hr, error, "OpenPolicy");
  110. }
  111. hr = LsaRetrievePrivateData(hPolicy, &lusSecretKeyName, &plusSecretData);
  112. LsaClose(hPolicy);
  113. if (!NT_SUCCESS(hr))
  114. {
  115. _PrintError2(hr, "LsaRetrievePrivateData", STATUS_OBJECT_NAME_NOT_FOUND);
  116. if ((HRESULT) STATUS_OBJECT_NAME_NOT_FOUND == hr)
  117. {
  118. hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
  119. }
  120. _JumpError2(hr, error, "LsaRetrievePrivateData", hr);
  121. }
  122. if (NULL == plusSecretData || NULL == plusSecretData->Buffer)
  123. {
  124. hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
  125. _JumpError(hr, error, "no data");
  126. }
  127. pwsz = (WCHAR const *) plusSecretData->Buffer;
  128. cwc = plusSecretData->Length / sizeof(WCHAR);
  129. for (cwcProfileName = 0; cwcProfileName < cwc; cwcProfileName++)
  130. {
  131. if (L'\0' == pwsz[cwcProfileName])
  132. {
  133. break;
  134. }
  135. }
  136. if (cwcProfileName == cwc)
  137. {
  138. hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
  139. _JumpError(hr, error, "bad data");
  140. }
  141. for (cwcLogonName = cwcProfileName + 1; cwcLogonName < cwc; cwcLogonName++)
  142. {
  143. if (L'\0' == pwsz[cwcLogonName])
  144. {
  145. break;
  146. }
  147. }
  148. if (cwcLogonName == cwc)
  149. {
  150. hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
  151. _JumpError(hr, error, "bad data");
  152. }
  153. cwcLogonName -= cwcProfileName + 1;
  154. cwcPassword = cwc - (cwcProfileName + 1 + cwcLogonName + 1);
  155. hr = SaveString(pwsz, cwcProfileName, &pwszProfileName);
  156. _JumpIfError(hr, error, "SaveString");
  157. hr = SaveString(&pwsz[cwcProfileName + 1], cwcLogonName, &pwszLogonName);
  158. _JumpIfError(hr, error, "SaveString");
  159. hr = SaveString(
  160. &pwsz[cwcProfileName + 1 + cwcLogonName + 1],
  161. cwcPassword,
  162. &pwszPassword);
  163. _JumpIfError(hr, error, "SaveString");
  164. *ppwszProfileName = pwszProfileName;
  165. pwszProfileName = NULL;
  166. *ppwszLogonName = pwszLogonName;
  167. pwszLogonName = NULL;
  168. *ppwszPassword = pwszPassword;
  169. pwszPassword = NULL;
  170. error:
  171. if (NULL != pwszProfileName)
  172. {
  173. ZeroMemory(pwszProfileName, cwcProfileName * sizeof(WCHAR));
  174. LocalFree(pwszProfileName);
  175. }
  176. if (NULL != pwszLogonName)
  177. {
  178. ZeroMemory(pwszLogonName, cwcLogonName * sizeof(WCHAR));
  179. LocalFree(pwszLogonName);
  180. }
  181. if (NULL != pwszPassword)
  182. {
  183. ZeroMemory(pwszPassword, cwcPassword * sizeof(WCHAR));
  184. LocalFree(pwszPassword);
  185. }
  186. if (NULL != plusSecretData)
  187. {
  188. if (NULL != plusSecretData->Buffer)
  189. {
  190. ZeroMemory(plusSecretData->Buffer, plusSecretData->Length);
  191. }
  192. LsaFreeMemory(plusSecretData);
  193. }
  194. return(hr);
  195. }
  196. //+--------------------------------------------------------------------------
  197. // mySaveMapiInfo -- Persist the specified Name/Password to a global LSA secret
  198. //+--------------------------------------------------------------------------
  199. HRESULT
  200. mySaveMapiInfo(
  201. OPTIONAL IN WCHAR const *pwszServerName,
  202. OUT WCHAR const *pwszProfileName,
  203. OUT WCHAR const *pwszLogonName,
  204. OUT WCHAR const *pwszPassword)
  205. {
  206. HRESULT hr;
  207. LSA_HANDLE hPolicy;
  208. UNICODE_STRING lusSecretKeyName;
  209. UNICODE_STRING lusSecretData;
  210. WCHAR wszSecret[MAX_PATH];
  211. DWORD cwc;
  212. WCHAR *pwsz;
  213. if (NULL == pwszProfileName ||
  214. NULL == pwszLogonName ||
  215. NULL == pwszPassword)
  216. {
  217. hr = E_POINTER;
  218. _JumpError(hr, error, "NULL parm");
  219. }
  220. cwc = lstrlen(pwszProfileName) + 1 +
  221. lstrlen(pwszLogonName) + 1 +
  222. lstrlen(pwszPassword);
  223. if (ARRAYSIZE(wszSecret) <= cwc)
  224. {
  225. hr = HRESULT_FROM_WIN32(ERROR_BUFFER_OVERFLOW);
  226. _JumpError(hr, error, "overflow");
  227. }
  228. pwsz = wszSecret;
  229. wcscpy(pwsz, pwszProfileName);
  230. pwsz += lstrlen(pwsz) + 1;
  231. wcscpy(pwsz, pwszLogonName);
  232. pwsz += lstrlen(pwsz) + 1;
  233. wcscpy(pwsz, pwszPassword);
  234. InitLsaString(&lusSecretData, wszSecret, cwc * sizeof(WCHAR));
  235. InitLsaString(&lusSecretKeyName, wszCERTMAPIINFO, MAXDWORD);
  236. hr = OpenPolicy(pwszServerName, POLICY_CREATE_SECRET, &hPolicy);
  237. if (!NT_SUCCESS(hr))
  238. {
  239. _JumpError(hr, error, "OpenPolicy");
  240. }
  241. hr = LsaStorePrivateData(hPolicy, &lusSecretKeyName, &lusSecretData);
  242. LsaClose(hPolicy);
  243. if (!NT_SUCCESS(hr))
  244. {
  245. _JumpError(hr, error, "LsaStorePrivateData");
  246. }
  247. hr = S_OK;
  248. error:
  249. ZeroMemory(wszSecret, sizeof(wszSecret));
  250. return(hr);
  251. }