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.

303 lines
7.4 KiB

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