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.

313 lines
7.3 KiB

  1. #include "stdafx.h"
  2. #include "setpass.h"
  3. #ifndef _CHICAGO_
  4. #include "inetinfo.h"
  5. #include "inetcom.h"
  6. //
  7. // Quick macro to initialize a unicode string
  8. //
  9. #define InitUnicodeString( pUnicode, pwch ) \
  10. { \
  11. (pUnicode)->Buffer = (PWCH)pwch; \
  12. (pUnicode)->Length = (pwch == NULL )? 0: (wcslen( pwch ) * sizeof(WCHAR)); \
  13. (pUnicode)->MaximumLength = (pUnicode)->Length + sizeof(WCHAR);\
  14. }
  15. BOOL GetSecret(
  16. IN LPCTSTR pszSecretName,
  17. OUT BUFFER * pbufSecret
  18. )
  19. /*++
  20. Description:
  21. Retrieves the specified unicode secret
  22. Arguments:
  23. pszSecretName - LSA Secret to retrieve
  24. pbufSecret - Receives found secret
  25. Returns:
  26. TRUE on success and FALSE if any failure.
  27. --*/
  28. {
  29. BOOL fResult;
  30. NTSTATUS ntStatus;
  31. PUNICODE_STRING punicodePassword = NULL;
  32. UNICODE_STRING unicodeSecret;
  33. LSA_HANDLE hPolicy;
  34. OBJECT_ATTRIBUTES ObjectAttributes;
  35. WCHAR wszSecretName[_MAX_PATH];
  36. #if defined(UNICODE) || defined(_UNICODE)
  37. _tcscpy(wszSecretName, pszSecretName);
  38. #else
  39. MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pszSecretName, -1, (LPWSTR)wszSecretName, _MAX_PATH);
  40. #endif
  41. //
  42. // Open a policy to the remote LSA
  43. //
  44. InitializeObjectAttributes( &ObjectAttributes,
  45. NULL,
  46. 0L,
  47. NULL,
  48. NULL );
  49. ntStatus = LsaOpenPolicy( NULL,
  50. &ObjectAttributes,
  51. POLICY_ALL_ACCESS,
  52. &hPolicy );
  53. if ( !NT_SUCCESS( ntStatus ) )
  54. {
  55. SetLastError( LsaNtStatusToWinError( ntStatus ) );
  56. return FALSE;
  57. }
  58. InitUnicodeString( &unicodeSecret, wszSecretName );
  59. //
  60. // Query the secret value.
  61. //
  62. ntStatus = LsaRetrievePrivateData( hPolicy,
  63. &unicodeSecret,
  64. &punicodePassword );
  65. if( NT_SUCCESS(ntStatus) && (NULL !=punicodePassword))
  66. {
  67. DWORD cbNeeded;
  68. cbNeeded = punicodePassword->Length + sizeof(WCHAR);
  69. if ( !pbufSecret->Resize( cbNeeded ) )
  70. {
  71. ntStatus = STATUS_NO_MEMORY;
  72. goto Failure;
  73. }
  74. memcpy( pbufSecret->QueryPtr(),
  75. punicodePassword->Buffer,
  76. punicodePassword->Length );
  77. *((WCHAR *) pbufSecret->QueryPtr() +
  78. punicodePassword->Length / sizeof(WCHAR)) = L'\0';
  79. RtlZeroMemory( punicodePassword->Buffer,
  80. punicodePassword->MaximumLength );
  81. }
  82. Failure:
  83. fResult = NT_SUCCESS(ntStatus);
  84. //
  85. // Cleanup & exit.
  86. //
  87. if( punicodePassword != NULL )
  88. {
  89. LsaFreeMemory( (PVOID)punicodePassword );
  90. }
  91. LsaClose( hPolicy );
  92. if ( !fResult )
  93. SetLastError( LsaNtStatusToWinError( ntStatus ));
  94. return fResult;
  95. }
  96. BOOL GetAnonymousSecret(
  97. IN LPCTSTR pszSecretName,
  98. OUT LPTSTR pszPassword
  99. )
  100. {
  101. BUFFER * pbufSecret = NULL;
  102. LPWSTR pwsz = NULL;
  103. pbufSecret = new BUFFER();
  104. if (pbufSecret)
  105. {
  106. if ( !GetSecret( pszSecretName, pbufSecret ))
  107. return FALSE;
  108. pwsz = (WCHAR *) pbufSecret->QueryPtr();
  109. if (pwsz)
  110. {
  111. #if defined(UNICODE) || defined(_UNICODE)
  112. _tcscpy(pszPassword, pwsz);
  113. #else
  114. WideCharToMultiByte( CP_ACP, 0, pwsz, -1, pszPassword, _MAX_PATH, NULL, NULL );
  115. #endif
  116. }
  117. delete(pbufSecret);
  118. pbufSecret = NULL;
  119. }
  120. return TRUE;
  121. }
  122. BOOL GetRootSecret(
  123. IN LPCTSTR pszRoot,
  124. IN LPCTSTR pszSecretName,
  125. OUT LPTSTR pszPassword
  126. )
  127. /*++
  128. Description:
  129. This function retrieves the password for the specified root & address
  130. Arguments:
  131. pszRoot - Name of root + address in the form "/root,<address>".
  132. pszSecretName - Virtual Root password secret name
  133. pszPassword - Receives password, must be at least PWLEN+1 characters
  134. Returns:
  135. TRUE on success and FALSE if any failure.
  136. --*/
  137. {
  138. BUFFER * pbufSecret = NULL;
  139. LPWSTR pwsz;
  140. LPWSTR pwszTerm;
  141. LPWSTR pwszNextLine;
  142. WCHAR wszRoot[_MAX_PATH];
  143. pbufSecret = new BUFFER();
  144. if (pbufSecret)
  145. {
  146. if ( !GetSecret( pszSecretName, pbufSecret ))
  147. return FALSE;
  148. pwsz = (WCHAR *) pbufSecret->QueryPtr();
  149. //
  150. // Scan the list of roots looking for a match. The list looks like:
  151. //
  152. // <root>,<address>=<password>\0
  153. // <root>,<address>=<password>\0
  154. // \0
  155. //
  156. #if defined(UNICODE) || defined(_UNICODE)
  157. _tcscpy(wszRoot, pszRoot);
  158. #else
  159. MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pszRoot, -1, (LPWSTR)wszRoot, _MAX_PATH);
  160. #endif
  161. while ( *pwsz )
  162. {
  163. pwszNextLine = pwsz + wcslen(pwsz) + 1;
  164. pwszTerm = wcschr( pwsz, L'=' );
  165. if ( !pwszTerm )
  166. goto NextLine;
  167. *pwszTerm = L'\0';
  168. if ( !_wcsicmp( wszRoot, pwsz ) )
  169. {
  170. DWORD cch;
  171. //
  172. // We found a match, copy the password
  173. //
  174. #if defined(UNICODE) || defined(_UNICODE)
  175. _tcscpy(pszPassword, pwszTerm+1);
  176. #else
  177. cch = WideCharToMultiByte( CP_ACP,
  178. WC_COMPOSITECHECK,
  179. pwszTerm + 1,
  180. -1,
  181. pszPassword,
  182. PWLEN + sizeof(CHAR),
  183. NULL,
  184. NULL );
  185. pszPassword[cch] = '\0';
  186. #endif
  187. return TRUE;
  188. }
  189. NextLine:
  190. pwsz = pwszNextLine;
  191. }
  192. //
  193. // If the matching root wasn't found, default to the empty password
  194. //
  195. *pszPassword = _T('\0');
  196. }
  197. if (pbufSecret)
  198. {
  199. delete(pbufSecret);
  200. pbufSecret = NULL;
  201. }
  202. return TRUE;
  203. }
  204. //
  205. // Saves password in LSA private data (LSA Secret).
  206. //
  207. DWORD SetSecret(IN LPCTSTR pszKeyName,IN LPCTSTR pszPassword)
  208. {
  209. DWORD dwError = E_FAIL;
  210. LSA_HANDLE hPolicy = NULL;
  211. try
  212. {
  213. LSA_OBJECT_ATTRIBUTES lsaoa = { sizeof(LSA_OBJECT_ATTRIBUTES), NULL, NULL, 0, NULL, NULL };
  214. dwError = LsaNtStatusToWinError(LsaOpenPolicy(NULL, &lsaoa, POLICY_CREATE_SECRET, &hPolicy));
  215. if (dwError != ERROR_SUCCESS)
  216. {
  217. dwError = HRESULT_FROM_WIN32(dwError);
  218. goto SetSecret_Exit;
  219. }
  220. USHORT usPasswordLength = wcslen(pszPassword) * sizeof(WCHAR);
  221. USHORT usKeyNameLength = wcslen(pszKeyName) * sizeof(WCHAR);
  222. LSA_UNICODE_STRING lsausKeyName = { usKeyNameLength, usKeyNameLength, const_cast<PWSTR>(pszKeyName) };
  223. LSA_UNICODE_STRING lsausPrivateData = { usPasswordLength, usPasswordLength, const_cast<PWSTR>(pszPassword) };
  224. dwError = LsaNtStatusToWinError(LsaStorePrivateData(hPolicy, &lsausKeyName, &lsausPrivateData));
  225. if (dwError != ERROR_SUCCESS)
  226. {
  227. dwError = HRESULT_FROM_WIN32(dwError);
  228. goto SetSecret_Exit;
  229. }
  230. LsaClose(hPolicy);
  231. }
  232. catch (...)
  233. {
  234. if (hPolicy)
  235. {
  236. LsaClose(hPolicy);
  237. }
  238. //throw;
  239. }
  240. SetSecret_Exit:
  241. return dwError;
  242. }
  243. #endif //_CHICAGO_