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.

482 lines
12 KiB

  1. //+----------------------------------------------------------------------------
  2. //
  3. // File: ntlsa.cpp
  4. //
  5. // Module: CMDIAL32.DLL
  6. //
  7. // Synopsis: This module contains the functions to allow Connection Manager to
  8. // interact with the NT LSA security system.
  9. //
  10. // Copyright (c) 1996-1999 Microsoft Corporation
  11. //
  12. // Author: henryt created 02/23/98
  13. // quintinb created Header 08/16/99
  14. //
  15. //+----------------------------------------------------------------------------
  16. #include "cmmaster.h"
  17. ///////////////////////////////////////////////////////////////////////////////////
  18. // defines
  19. ///////////////////////////////////////////////////////////////////////////////////
  20. #ifndef STATUS_SUCCESS
  21. #define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
  22. #endif
  23. #define InitializeLsaObjectAttributes( p, n, a, r, s ) { \
  24. (p)->Length = sizeof( LSA_OBJECT_ATTRIBUTES ); \
  25. (p)->RootDirectory = r; \
  26. (p)->Attributes = a; \
  27. (p)->ObjectName = n; \
  28. (p)->SecurityDescriptor = s; \
  29. (p)->SecurityQualityOfService = NULL; \
  30. }
  31. ///////////////////////////////////////////////////////////////////////////////////
  32. // typedef's
  33. ///////////////////////////////////////////////////////////////////////////////////
  34. ///////////////////////////////////////////////////////////////////////////////////
  35. // func prototypes
  36. ///////////////////////////////////////////////////////////////////////////////////
  37. void InitLsaString(
  38. PLSA_UNICODE_STRING pLsaString,
  39. LPWSTR pszString
  40. );
  41. ///////////////////////////////////////////////////////////////////////////////////
  42. // globals
  43. ///////////////////////////////////////////////////////////////////////////////////
  44. ///////////////////////////////////////////////////////////////////////////////////
  45. // Implementation
  46. ///////////////////////////////////////////////////////////////////////////////////
  47. //+---------------------------------------------------------------------------
  48. //
  49. // Function: LSA_ReadString
  50. //
  51. // Synopsis: Read a string from the NT Local Security Authority (LSA)
  52. // store.
  53. //
  54. // Arguments: pszKey The key to identify the string.
  55. // pszStr The buffer in which the string is to be
  56. // written to.
  57. // dwStrLen The length of the string buffer in bytes.
  58. //
  59. // Returns: DWORD 0 for SUCCES
  60. // GetLastError() for FAILURE
  61. //
  62. // History: henryt Created 5/15/97
  63. //
  64. //----------------------------------------------------------------------------
  65. DWORD LSA_ReadString(
  66. ArgsStruct *pArgs,
  67. LPTSTR pszKey,
  68. LPTSTR pszStr,
  69. DWORD dwStrLen
  70. )
  71. {
  72. DWORD dwErr;
  73. LSA_OBJECT_ATTRIBUTES oaObjAttr;
  74. LSA_HANDLE hPolicy = NULL;
  75. NTSTATUS ntStatus = STATUS_SUCCESS;
  76. LSA_UNICODE_STRING unicodeKey;
  77. PLSA_UNICODE_STRING punicodeValue = NULL;
  78. #if !defined(_UNICODE) && !defined(UNICODE)
  79. LPWSTR pszUnicodeKey = NULL;
  80. #endif
  81. if (!pszKey || !pszStr)
  82. {
  83. CMASSERTMSG(FALSE, TEXT("LSA_ReadString -- Invalid Parameter passed."));
  84. return ERROR_INVALID_PARAMETER;
  85. }
  86. //
  87. // Open the LSA secret space for writing.
  88. //
  89. InitializeLsaObjectAttributes(&oaObjAttr, NULL, 0L, NULL, NULL);
  90. ntStatus = pArgs->llsLsaLink.pfnOpenPolicy(NULL, &oaObjAttr, POLICY_READ, &hPolicy);
  91. if (ntStatus == STATUS_SUCCESS)
  92. {
  93. #if !defined(_UNICODE) && !defined(UNICODE)
  94. //
  95. // need to convert the ANSI key to unicode
  96. //
  97. if (!(pszUnicodeKey = (LPWSTR)CmMalloc((lstrlenA(pszKey)+1)*sizeof(WCHAR))))
  98. {
  99. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  100. goto exit;
  101. }
  102. if (!MultiByteToWideChar(CP_ACP, 0, pszKey, -1, pszUnicodeKey, (lstrlenA(pszKey)+1)*sizeof(WCHAR)))
  103. {
  104. CmFree(pszUnicodeKey);
  105. dwErr = ERROR_INVALID_DATA;
  106. goto exit;
  107. }
  108. //
  109. // create a unicode key
  110. //
  111. InitLsaString(&unicodeKey, pszUnicodeKey);
  112. CmFree(pszUnicodeKey);
  113. #else
  114. //
  115. // create a unicode key
  116. //
  117. InitLsaString(&unicodeKey, pszKey);
  118. #endif
  119. //
  120. // get it
  121. //
  122. ntStatus = pArgs->llsLsaLink.pfnRetrievePrivateData(hPolicy, &unicodeKey, &punicodeValue);
  123. }
  124. if (ntStatus != STATUS_SUCCESS)
  125. {
  126. dwErr = pArgs->llsLsaLink.pfnNtStatusToWinError(ntStatus);
  127. #ifdef DEBUG
  128. if (ERROR_SUCCESS != dwErr)
  129. {
  130. if (ERROR_FILE_NOT_FOUND == dwErr)
  131. {
  132. CMTRACE(TEXT("LSA_ReadPassword() NT password not found."));
  133. }
  134. else
  135. {
  136. CMTRACE1(TEXT("LSA_ReadPassword() NT failed, err=%u"), dwErr);
  137. }
  138. }
  139. #endif
  140. }
  141. else
  142. {
  143. if (dwStrLen < punicodeValue->Length)
  144. {
  145. dwErr = ERROR_BUFFER_OVERFLOW;
  146. goto exit;
  147. }
  148. #if !defined(_UNICODE) && !defined(UNICODE)
  149. if (!WideCharToMultiByte(CP_ACP, 0, punicodeValue->Buffer, -1,
  150. pszStr, dwStrLen, NULL, NULL))
  151. {
  152. dwErr = ERROR_INVALID_DATA;
  153. goto exit;
  154. }
  155. #else
  156. CopyMemory((PVOID)pszStr, (CONST PVOID)punicodeValue->Buffer, punicodeValue->Length);
  157. #endif
  158. dwErr = 0;
  159. }
  160. exit:
  161. if (punicodeValue)
  162. {
  163. pArgs->llsLsaLink.pfnFreeMemory(punicodeValue);
  164. }
  165. if (hPolicy)
  166. {
  167. pArgs->llsLsaLink.pfnClose(hPolicy);
  168. }
  169. return dwErr;
  170. }
  171. //+---------------------------------------------------------------------------
  172. //
  173. // Function: LSA_WriteString
  174. //
  175. // Synopsis: Write a string to the NT Local Security Authority (LSA)
  176. // store.
  177. //
  178. // Arguments: pszKey The key to identify the string.
  179. // pszStr The string. This function deletes the
  180. // string if this param is NULL.
  181. //
  182. // Returns: DWORD 0 for SUCCES
  183. // GetLastError() for FAILURE
  184. //
  185. // History: henryt Created 5/15/97
  186. //
  187. //----------------------------------------------------------------------------
  188. DWORD LSA_WriteString(
  189. ArgsStruct *pArgs,
  190. LPTSTR pszKey,
  191. LPCTSTR pszStr
  192. )
  193. {
  194. DWORD dwErr = 0;
  195. LSA_OBJECT_ATTRIBUTES oaObjAttr;
  196. LSA_HANDLE hPolicy = NULL;
  197. NTSTATUS ntStatus = STATUS_SUCCESS;
  198. LSA_UNICODE_STRING unicodeKey;
  199. LSA_UNICODE_STRING unicodeValue;
  200. #if !defined(_UNICODE) && !defined(UNICODE)
  201. LPWSTR pszUnicodeKey = NULL;
  202. LPWSTR pszUnicodePassword = NULL;
  203. #endif
  204. if (!pszKey)
  205. {
  206. return ERROR_INVALID_PARAMETER;
  207. }
  208. //
  209. // Open the LSA secret space for writing.
  210. //
  211. InitializeLsaObjectAttributes(&oaObjAttr, NULL, 0L, NULL, NULL);
  212. ntStatus = pArgs->llsLsaLink.pfnOpenPolicy(NULL, &oaObjAttr, POLICY_WRITE, &hPolicy);
  213. if (ntStatus == STATUS_SUCCESS)
  214. {
  215. #if !defined(_UNICODE) && !defined(UNICODE)
  216. //
  217. // need to convert the ANSI key to unicode
  218. //
  219. if (!(pszUnicodeKey = (LPWSTR)CmMalloc((lstrlenA(pszKey)+1)*sizeof(WCHAR))))
  220. {
  221. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  222. goto exit;
  223. }
  224. if (!MultiByteToWideChar(CP_ACP, 0, pszKey, -1, pszUnicodeKey, (lstrlenA(pszKey)+1)*sizeof(WCHAR)))
  225. {
  226. dwErr = ERROR_INVALID_DATA;
  227. goto exit;
  228. }
  229. if (pszStr)
  230. {
  231. if (!(pszUnicodePassword = (LPWSTR)CmMalloc((lstrlenA(pszStr)+1)*sizeof(WCHAR))))
  232. {
  233. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  234. goto exit;
  235. }
  236. if (!MultiByteToWideChar(CP_ACP, 0, pszStr, -1, pszUnicodePassword, (lstrlenA(pszStr)+1)*sizeof(WCHAR)))
  237. {
  238. dwErr = ERROR_INVALID_DATA;
  239. goto exit;
  240. }
  241. }
  242. //
  243. // create a unicode key
  244. //
  245. InitLsaString(&unicodeKey, pszUnicodeKey);
  246. if (pszStr)
  247. {
  248. //
  249. // set the data
  250. //
  251. unicodeValue.Length = (lstrlenU(pszUnicodePassword)+1)*sizeof(WCHAR);
  252. unicodeValue.Buffer = (PWSTR)pszUnicodePassword;
  253. }
  254. #else
  255. //
  256. // create a unicode key
  257. //
  258. InitLsaString(&unicodeKey, pszKey);
  259. if (pszStr)
  260. {
  261. //
  262. // set the data
  263. //
  264. unicodeValue.Length = (lstrlenU(pszStr)+1)*sizeof(TCHAR);
  265. unicodeValue.Buffer = (PWSTR)pszStr;
  266. }
  267. #endif
  268. //
  269. // save it
  270. //
  271. ntStatus = pArgs->llsLsaLink.pfnStorePrivateData(hPolicy, &unicodeKey, pszStr? &unicodeValue : NULL);
  272. }
  273. if (ntStatus != STATUS_SUCCESS)
  274. {
  275. dwErr = pArgs->llsLsaLink.pfnNtStatusToWinError(ntStatus);
  276. #ifdef DEBUG
  277. if (ERROR_SUCCESS != dwErr)
  278. {
  279. if (ERROR_FILE_NOT_FOUND == dwErr)
  280. {
  281. CMTRACE(TEXT("LSA_WritePassword() NT password not found."));
  282. }
  283. else
  284. {
  285. CMTRACE1(TEXT("LSA_WritePassword() NT failed, err=%u"), dwErr);
  286. }
  287. }
  288. #endif
  289. }
  290. if (hPolicy)
  291. {
  292. pArgs->llsLsaLink.pfnClose(hPolicy);
  293. }
  294. #if !defined(_UNICODE) && !defined(UNICODE)
  295. if (pszUnicodeKey)
  296. {
  297. CmFree(pszUnicodeKey);
  298. }
  299. if (pszUnicodePassword)
  300. {
  301. CmFree(pszUnicodePassword);
  302. }
  303. #endif
  304. return dwErr;
  305. }
  306. //+---------------------------------------------------------------------------
  307. //
  308. // Function: InitLsaString
  309. //
  310. // Synopsis: Init a LSA string.
  311. //
  312. // Arguments: pLsaString A LSA unicode string.
  313. // pszString An unicode string.
  314. //
  315. // Returns: None
  316. //
  317. // History: henryt Created 5/15/97
  318. //
  319. //----------------------------------------------------------------------------
  320. void InitLsaString(
  321. PLSA_UNICODE_STRING pLsaString,
  322. LPWSTR pszString
  323. )
  324. {
  325. DWORD dwStringLength;
  326. if (pszString == NULL)
  327. {
  328. pLsaString->Buffer = NULL;
  329. pLsaString->Length = 0;
  330. pLsaString->MaximumLength = 0;
  331. return;
  332. }
  333. dwStringLength = lstrlenU(pszString);
  334. pLsaString->Buffer = pszString;
  335. pLsaString->Length = (USHORT) dwStringLength * sizeof(WCHAR);
  336. pLsaString->MaximumLength=(USHORT)(dwStringLength+1) * sizeof(WCHAR);
  337. }
  338. //+---------------------------------------------------------------------------
  339. //
  340. // Function: InitLsa
  341. //
  342. // Synopsis: Basically does GetProcAddress()'s for all the LSA API's that
  343. // we need since these API's don't exist in the Windows95 version
  344. // of advapi32.dll.
  345. //
  346. // Arguments: NONE
  347. //
  348. // Returns: TRUE if SUCCESS
  349. // FALSE otherwise.
  350. //
  351. // History: henryt Created 5/15/97
  352. //
  353. //----------------------------------------------------------------------------
  354. BOOL InitLsa(
  355. ArgsStruct *pArgs
  356. )
  357. {
  358. LPCSTR apszLsa[] = {
  359. "LsaOpenPolicy",
  360. "LsaRetrievePrivateData",
  361. "LsaStorePrivateData",
  362. "LsaNtStatusToWinError",
  363. "LsaClose",
  364. "LsaFreeMemory",
  365. NULL
  366. };
  367. MYDBGASSERT(sizeof(pArgs->llsLsaLink.apvPfnLsa)/sizeof(pArgs->llsLsaLink.apvPfnLsa[0]) ==
  368. sizeof(apszLsa)/sizeof(apszLsa[0]));
  369. ZeroMemory(&pArgs->llsLsaLink, sizeof(pArgs->llsLsaLink));
  370. return (LinkToDll(&pArgs->llsLsaLink.hInstLsa,
  371. "advapi32.dll",
  372. apszLsa,
  373. pArgs->llsLsaLink.apvPfnLsa));
  374. }
  375. //+---------------------------------------------------------------------------
  376. //
  377. // Function: DeInitLsa
  378. //
  379. // Synopsis: The reverse of InitLsa().
  380. //
  381. // Arguments: NONE
  382. //
  383. // Returns: TRUE if SUCCESS
  384. // FALSE otherwise.
  385. //
  386. // History: henryt Created 5/15/97
  387. //
  388. //----------------------------------------------------------------------------
  389. BOOL DeInitLsa(
  390. ArgsStruct *pArgs
  391. )
  392. {
  393. if (pArgs->llsLsaLink.hInstLsa)
  394. {
  395. FreeLibrary(pArgs->llsLsaLink.hInstLsa);
  396. }
  397. ZeroMemory(&pArgs->llsLsaLink, sizeof(pArgs->llsLsaLink));
  398. return TRUE;
  399. }