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.

310 lines
7.8 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 TSTR *strSecret
  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 ( ( _tcslen( wszSecretName ) / sizeof (TCHAR) ) >= MAXUSHORT )
  37. {
  38. // Lets check to make sure that the implicit conversion in
  39. // InitUnicodeString further down is not a problem
  40. return FALSE;
  41. }
  42. #if defined(UNICODE) || defined(_UNICODE)
  43. _tcscpy(wszSecretName, pszSecretName);
  44. #else
  45. MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pszSecretName, -1, (LPWSTR)wszSecretName, _MAX_PATH);
  46. #endif
  47. //
  48. // Open a policy to the remote LSA
  49. //
  50. InitializeObjectAttributes( &ObjectAttributes,
  51. NULL,
  52. 0L,
  53. NULL,
  54. NULL );
  55. ntStatus = LsaOpenPolicy( NULL,
  56. &ObjectAttributes,
  57. POLICY_ALL_ACCESS,
  58. &hPolicy );
  59. if ( !NT_SUCCESS( ntStatus ) )
  60. {
  61. SetLastError( LsaNtStatusToWinError( ntStatus ) );
  62. return FALSE;
  63. }
  64. #pragma warning( disable : 4244 )
  65. // InitUnicodeString is a #def, that does a implicit conversion from size_t to
  66. // USHORT. Since I can not change the #def, I am disabling the warning
  67. InitUnicodeString( &unicodeSecret, wszSecretName );
  68. #pragma warning( default : 4244 )
  69. //
  70. // Query the secret value.
  71. //
  72. ntStatus = LsaRetrievePrivateData( hPolicy,
  73. &unicodeSecret,
  74. &punicodePassword );
  75. if( NT_SUCCESS(ntStatus) && (NULL !=punicodePassword))
  76. {
  77. DWORD cbNeeded;
  78. cbNeeded = punicodePassword->Length + sizeof(WCHAR);
  79. strSecret->MarkSensitiveData( TRUE );
  80. if ( !strSecret->Resize( cbNeeded ) )
  81. {
  82. ntStatus = STATUS_NO_MEMORY;
  83. goto Failure;
  84. }
  85. memcpy( strSecret->QueryStr(),
  86. punicodePassword->Buffer,
  87. punicodePassword->Length );
  88. *((WCHAR *) strSecret->QueryStr() +
  89. punicodePassword->Length / sizeof(WCHAR)) = L'\0';
  90. SecureZeroMemory( punicodePassword->Buffer,
  91. punicodePassword->MaximumLength );
  92. }
  93. else if ( !NT_SUCCESS(ntStatus) )
  94. {
  95. ntStatus = STATUS_UNSUCCESSFUL;
  96. }
  97. Failure:
  98. fResult = NT_SUCCESS(ntStatus);
  99. //
  100. // Cleanup & exit.
  101. //
  102. if( punicodePassword != NULL )
  103. {
  104. LsaFreeMemory( (PVOID)punicodePassword );
  105. }
  106. LsaClose( hPolicy );
  107. if ( !fResult )
  108. SetLastError( LsaNtStatusToWinError( ntStatus ));
  109. return fResult;
  110. }
  111. BOOL GetAnonymousSecret(
  112. IN LPCTSTR pszSecretName,
  113. OUT TSTR *pstrPassword
  114. )
  115. {
  116. LPWSTR pwsz = NULL;
  117. BOOL bRet = FALSE;
  118. BUFFER bufSecret;
  119. // Mark this password as sensitive data
  120. pstrPassword->MarkSensitiveData( TRUE );
  121. if ( !GetSecret( pszSecretName, pstrPassword ))
  122. {
  123. return FALSE;
  124. }
  125. return TRUE;
  126. }
  127. BOOL GetRootSecret(
  128. IN LPCTSTR pszRoot,
  129. IN LPCTSTR pszSecretName,
  130. OUT LPTSTR pszPassword
  131. )
  132. /*++
  133. Description:
  134. This function retrieves the password for the specified root & address
  135. Arguments:
  136. pszRoot - Name of root + address in the form "/root,<address>".
  137. pszSecretName - Virtual Root password secret name
  138. pszPassword - Receives password, must be at least PWLEN+1 characters
  139. Returns:
  140. TRUE on success and FALSE if any failure.
  141. --*/
  142. {
  143. TSTR strSecret;
  144. LPWSTR pwsz;
  145. LPWSTR pwszTerm;
  146. LPWSTR pwszNextLine;
  147. WCHAR wszRoot[_MAX_PATH];
  148. if ( !GetSecret( pszSecretName, &strSecret ))
  149. return FALSE;
  150. pwsz = strSecret.QueryStr();
  151. //
  152. // Scan the list of roots looking for a match. The list looks like:
  153. //
  154. // <root>,<address>=<password>\0
  155. // <root>,<address>=<password>\0
  156. // \0
  157. //
  158. #if defined(UNICODE) || defined(_UNICODE)
  159. _tcscpy(wszRoot, pszRoot);
  160. #else
  161. MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pszRoot, -1, (LPWSTR)wszRoot, _MAX_PATH);
  162. #endif
  163. while ( *pwsz )
  164. {
  165. pwszNextLine = pwsz + wcslen(pwsz) + 1;
  166. pwszTerm = wcschr( pwsz, L'=' );
  167. if ( !pwszTerm )
  168. goto NextLine;
  169. *pwszTerm = L'\0';
  170. if ( !_wcsicmp( wszRoot, pwsz ) )
  171. {
  172. //
  173. // We found a match, copy the password
  174. //
  175. #if defined(UNICODE) || defined(_UNICODE)
  176. _tcscpy(pszPassword, pwszTerm+1);
  177. #else
  178. cch = WideCharToMultiByte( CP_ACP,
  179. WC_COMPOSITECHECK,
  180. pwszTerm + 1,
  181. -1,
  182. pszPassword,
  183. PWLEN + sizeof(CHAR),
  184. NULL,
  185. NULL );
  186. pszPassword[cch] = '\0';
  187. #endif
  188. return TRUE;
  189. }
  190. NextLine:
  191. pwsz = pwszNextLine;
  192. }
  193. //
  194. // If the matching root wasn't found, default to the empty password
  195. //
  196. *pszPassword = _T('\0');
  197. return TRUE;
  198. }
  199. //
  200. // Saves password in LSA private data (LSA Secret).
  201. //
  202. DWORD SetSecret(IN LPCTSTR pszKeyName,IN LPCTSTR pszPassword)
  203. {
  204. DWORD dwError = ERROR_NOT_ENOUGH_MEMORY;
  205. LSA_HANDLE hPolicy = NULL;
  206. DWORD dwPasswordSize = wcslen(pszPassword) * sizeof(WCHAR);
  207. DWORD dwKeyNameSize = wcslen(pszKeyName) * sizeof(WCHAR);
  208. if ( ( dwPasswordSize >= MAXUSHORT ) ||
  209. ( dwKeyNameSize >= MAXUSHORT )
  210. )
  211. {
  212. return dwError;
  213. }
  214. try
  215. {
  216. LSA_OBJECT_ATTRIBUTES lsaoa = { sizeof(LSA_OBJECT_ATTRIBUTES), NULL, NULL, 0, NULL, NULL };
  217. dwError = LsaNtStatusToWinError( LsaOpenPolicy(NULL, &lsaoa, POLICY_CREATE_SECRET, &hPolicy) );
  218. if ( dwError != ERROR_SUCCESS )
  219. {
  220. return dwError;
  221. }
  222. LSA_UNICODE_STRING lsausKeyName = { (USHORT) dwKeyNameSize,
  223. (USHORT) dwKeyNameSize,
  224. const_cast<PWSTR>(pszKeyName) };
  225. LSA_UNICODE_STRING lsausPrivateData = { (USHORT) dwPasswordSize,
  226. (USHORT) dwPasswordSize,
  227. const_cast<PWSTR>(pszPassword) };
  228. dwError = LsaNtStatusToWinError( LsaStorePrivateData(hPolicy, &lsausKeyName, &lsausPrivateData) );
  229. }
  230. catch (...)
  231. {
  232. dwError = ERROR_NOT_ENOUGH_MEMORY;
  233. }
  234. if (hPolicy)
  235. {
  236. LsaClose(hPolicy);
  237. }
  238. return dwError;
  239. }
  240. #endif //_CHICAGO_