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.

539 lines
10 KiB

  1. /*++
  2. Copyright (c) 1990 Microsoft Corporation
  3. Module Name:
  4. creden.cxx
  5. Abstract:
  6. This module abstracts user credentials for the multiple credential support.
  7. Author:
  8. Krishna Ganugapati (KrishnaG) 03-Aug-1996
  9. Revision History:
  10. --*/
  11. extern "C" {
  12. #include <nt.h>
  13. #include <ntrtl.h>
  14. #include <nturtl.h>
  15. #include <windows.h>
  16. #include <imagehlp.h>
  17. #include <stdio.h>
  18. #include <stdlib.h>
  19. #include "memory.h"
  20. }
  21. #include <basetyps.h>
  22. #include <des.h>
  23. #include <crypt.h>
  24. typedef long HRESULT;
  25. #include "misc.hxx"
  26. #include "creden.hxx"
  27. #include "macro.h"
  28. //
  29. // This routine allocates and stores the password in the
  30. // passed in pointer. The assumption here is that pszString
  31. // is valid, it can be an empty string but not NULL.
  32. // Note that this code cannot be used as is on Win2k and below
  33. // as they do not support the newer functions.
  34. //
  35. HRESULT
  36. EncryptString(
  37. LPWSTR pszString,
  38. LPWSTR *ppszSafeString,
  39. PDWORD pdwLen
  40. )
  41. {
  42. HRESULT hr = S_OK;
  43. DWORD dwLenStr = 0;
  44. DWORD dwPwdLen = 0;
  45. LPWSTR pszTempStr = NULL;
  46. NTSTATUS errStatus = STATUS_SUCCESS;
  47. *ppszSafeString = NULL;
  48. *pdwLen = 0;
  49. //
  50. // If the string is valid, then we need to get the length
  51. // and initialize the unicode string.
  52. //
  53. if (pszString) {
  54. UNICODE_STRING Password;
  55. //
  56. // Determine the length of buffer taking padding into account.
  57. //
  58. dwLenStr = wcslen(pszString);
  59. dwPwdLen = (dwLenStr + 1) * sizeof(WCHAR) + (DES_BLOCKLEN -1);
  60. pszTempStr = (LPWSTR) AllocADsMem(dwPwdLen);
  61. if (!pszTempStr) {
  62. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  63. }
  64. wcscpy(pszTempStr, pszString);
  65. RtlInitUnicodeString(&Password, pszTempStr);
  66. USHORT usExtra = 0;
  67. if (usExtra = (Password.MaximumLength % DES_BLOCKLEN)) {
  68. Password.MaximumLength += (DES_BLOCKLEN - usExtra);
  69. }
  70. errStatus = RtlEncryptMemory(
  71. Password.Buffer,
  72. Password.MaximumLength,
  73. 0
  74. );
  75. if (errStatus != STATUS_SUCCESS) {
  76. BAIL_ON_FAILURE(hr = HRESULT_FROM_NT(errStatus));
  77. }
  78. *pdwLen = Password.MaximumLength;
  79. *ppszSafeString = pszTempStr;
  80. }
  81. error:
  82. if (FAILED(hr) && pszTempStr) {
  83. SecureZeroMemory(pszTempStr, dwLenStr*sizeof(WCHAR));
  84. FreeADsMem(pszTempStr);
  85. }
  86. RRETURN(hr);
  87. }
  88. HRESULT
  89. DecryptString(
  90. LPWSTR pszEncodedString,
  91. LPWSTR *ppszString,
  92. DWORD dwLen
  93. )
  94. {
  95. HRESULT hr = S_OK;
  96. LPWSTR pszTempStr = NULL;
  97. UNICODE_STRING Password;
  98. NTSTATUS errStatus;
  99. if (!dwLen || !ppszString) {
  100. RRETURN(E_FAIL);
  101. }
  102. *ppszString = NULL;
  103. if (dwLen) {
  104. pszTempStr = (LPWSTR) AllocADsMem(dwLen);
  105. if (!pszTempStr) {
  106. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  107. }
  108. memcpy(pszTempStr, pszEncodedString, dwLen);
  109. errStatus = RtlDecryptMemory(pszTempStr, dwLen, 0);
  110. if (errStatus != STATUS_SUCCESS) {
  111. BAIL_ON_FAILURE(hr = HRESULT_FROM_NT(errStatus));
  112. }
  113. *ppszString = pszTempStr;
  114. }
  115. error:
  116. if (FAILED(hr) && pszTempStr) {
  117. SecureZeroMemory(pszTempStr, dwLen);
  118. FreeADsStr(pszTempStr);
  119. }
  120. RRETURN(hr);
  121. }
  122. //
  123. // Static member of the class
  124. //
  125. CCredentials::CCredentials():
  126. _lpszUserName(NULL),
  127. _lpszPassword(NULL),
  128. _dwAuthFlags(0),
  129. _dwPasswordLen(0)
  130. {
  131. }
  132. CCredentials::CCredentials(
  133. LPWSTR lpszUserName,
  134. LPWSTR lpszPassword,
  135. DWORD dwAuthFlags
  136. ):
  137. _lpszUserName(NULL),
  138. _lpszPassword(NULL),
  139. _dwAuthFlags(0),
  140. _dwPasswordLen(0)
  141. {
  142. //
  143. // AjayR 10-04-99 we need a way to bail if the
  144. // alloc's fail. Since it is in the constructor this is
  145. // not very easy to do.
  146. //
  147. if (lpszUserName) {
  148. _lpszUserName = AllocADsStr(lpszUserName);
  149. }
  150. else {
  151. _lpszUserName = NULL;
  152. }
  153. if (lpszPassword) {
  154. //
  155. // The call can fail but we cannot recover from this.
  156. //
  157. EncryptString(
  158. lpszPassword,
  159. &_lpszPassword,
  160. &_dwPasswordLen
  161. );
  162. }else {
  163. _lpszPassword = NULL;
  164. }
  165. _dwAuthFlags = dwAuthFlags;
  166. }
  167. CCredentials::~CCredentials()
  168. {
  169. if (_lpszUserName) {
  170. FreeADsStr(_lpszUserName);
  171. }
  172. if (_lpszPassword) {
  173. FreeADsStr(_lpszPassword);
  174. }
  175. }
  176. HRESULT
  177. CCredentials::GetUserName(
  178. LPWSTR *lppszUserName
  179. )
  180. {
  181. if (!lppszUserName) {
  182. RRETURN(E_FAIL);
  183. }
  184. if (!_lpszUserName) {
  185. *lppszUserName = NULL;
  186. }else {
  187. *lppszUserName = AllocADsStr(_lpszUserName);
  188. if (!*lppszUserName) {
  189. RRETURN(E_OUTOFMEMORY);
  190. }
  191. }
  192. RRETURN(S_OK);
  193. }
  194. HRESULT
  195. CCredentials::GetPassword(
  196. LPWSTR * lppszPassword
  197. )
  198. {
  199. UNICODE_STRING Password;
  200. LPWSTR lpTempPassword = NULL;
  201. Password.Length = 0;
  202. if (!lppszPassword) {
  203. RRETURN(E_FAIL);
  204. }
  205. if (!_lpszPassword) {
  206. *lppszPassword = NULL;
  207. }else {
  208. RRETURN(
  209. DecryptString(
  210. _lpszPassword,
  211. lppszPassword,
  212. _dwPasswordLen
  213. )
  214. );
  215. }
  216. RRETURN(S_OK);
  217. }
  218. HRESULT
  219. CCredentials::SetUserName(
  220. LPWSTR lpszUserName
  221. )
  222. {
  223. if (_lpszUserName) {
  224. FreeADsStr(_lpszUserName);
  225. }
  226. if (!lpszUserName) {
  227. _lpszUserName = NULL;
  228. RRETURN(S_OK);
  229. }
  230. _lpszUserName = AllocADsStr(
  231. lpszUserName
  232. );
  233. if(!_lpszUserName) {
  234. RRETURN(E_FAIL);
  235. }
  236. RRETURN(S_OK);
  237. }
  238. HRESULT
  239. CCredentials::SetPassword(
  240. LPWSTR lpszPassword
  241. )
  242. {
  243. if (_lpszPassword) {
  244. FreeADsStr(_lpszPassword);
  245. }
  246. if (!lpszPassword) {
  247. _lpszPassword = NULL;
  248. RRETURN(S_OK);
  249. }
  250. RRETURN(
  251. EncryptString(
  252. lpszPassword,
  253. &_lpszPassword,
  254. &_dwPasswordLen
  255. )
  256. );
  257. }
  258. CCredentials::CCredentials(
  259. const CCredentials& Credentials
  260. )
  261. {
  262. HRESULT hr = S_OK;
  263. LPWSTR pszTmpPwd = NULL;
  264. _lpszUserName = NULL;
  265. _lpszPassword = NULL;
  266. _lpszUserName = AllocADsStr(
  267. Credentials._lpszUserName
  268. );
  269. if (Credentials._lpszPassword) {
  270. hr = DecryptString(
  271. Credentials._lpszPassword,
  272. &pszTmpPwd,
  273. Credentials._dwPasswordLen
  274. );
  275. }
  276. if (SUCCEEDED(hr) && pszTmpPwd) {
  277. hr = EncryptString(
  278. pszTmpPwd,
  279. &_lpszPassword,
  280. &_dwPasswordLen
  281. );
  282. }
  283. if (pszTmpPwd) {
  284. SecureZeroMemory(pszTmpPwd, wcslen(pszTmpPwd)*sizeof(WCHAR));
  285. FreeADsStr(pszTmpPwd);
  286. }
  287. _dwAuthFlags = Credentials._dwAuthFlags;
  288. }
  289. void
  290. CCredentials::operator=(
  291. const CCredentials& other
  292. )
  293. {
  294. HRESULT hr = S_OK;
  295. LPWSTR pszTmpPwd = NULL;
  296. if ( &other == this) {
  297. return;
  298. }
  299. if (_lpszUserName) {
  300. FreeADsStr(_lpszUserName);
  301. }
  302. if (_lpszPassword) {
  303. FreeADsStr(_lpszPassword);
  304. _lpszPassword = NULL;
  305. }
  306. _lpszUserName = AllocADsStr(
  307. other._lpszUserName
  308. );
  309. if (other._lpszPassword) {
  310. hr = DecryptString(
  311. other._lpszPassword,
  312. &pszTmpPwd,
  313. other._dwPasswordLen
  314. );
  315. }
  316. if (SUCCEEDED(hr) && pszTmpPwd) {
  317. hr = EncryptString(
  318. pszTmpPwd,
  319. &_lpszPassword,
  320. &_dwPasswordLen
  321. );
  322. }
  323. if (pszTmpPwd) {
  324. SecureZeroMemory(pszTmpPwd, wcslen(pszTmpPwd)*sizeof(WCHAR));
  325. FreeADsStr(pszTmpPwd);
  326. }
  327. _dwAuthFlags = other._dwAuthFlags;
  328. return;
  329. }
  330. BOOL
  331. operator==(
  332. CCredentials& x,
  333. CCredentials& y
  334. )
  335. {
  336. BOOL bEqualUser = FALSE;
  337. BOOL bEqualPassword = FALSE;
  338. BOOL bEqualFlags = FALSE;
  339. LPWSTR lpszXPassword = NULL;
  340. LPWSTR lpszYPassword = NULL;
  341. BOOL bReturnCode = FALSE;
  342. HRESULT hr = S_OK;
  343. if (x._lpszUserName && y._lpszUserName) {
  344. bEqualUser = !(wcscmp(x._lpszUserName, y._lpszUserName));
  345. }else if (!x._lpszUserName && !y._lpszUserName){
  346. bEqualUser = TRUE;
  347. }
  348. hr = x.GetPassword(&lpszXPassword);
  349. if (FAILED(hr)) {
  350. goto error;
  351. }
  352. hr = y.GetPassword(&lpszYPassword);
  353. if (FAILED(hr)) {
  354. goto error;
  355. }
  356. if ((lpszXPassword && lpszYPassword)) {
  357. bEqualPassword = !(wcscmp(lpszXPassword, lpszYPassword));
  358. }else if (!lpszXPassword && !lpszYPassword) {
  359. bEqualPassword = TRUE;
  360. }
  361. if (x._dwAuthFlags == y._dwAuthFlags) {
  362. bEqualFlags = TRUE;
  363. }
  364. if (bEqualUser && bEqualPassword && bEqualFlags) {
  365. bReturnCode = TRUE;
  366. }
  367. error:
  368. if (lpszXPassword) {
  369. SecureZeroMemory(lpszXPassword, wcslen(lpszXPassword)*sizeof(WCHAR));
  370. FreeADsStr(lpszXPassword);
  371. }
  372. if (lpszYPassword) {
  373. SecureZeroMemory(lpszYPassword, wcslen(lpszYPassword)*sizeof(WCHAR));
  374. FreeADsStr(lpszYPassword);
  375. }
  376. return(bReturnCode);
  377. }
  378. BOOL
  379. CCredentials::IsNullCredentials(
  380. )
  381. {
  382. // The function will return true even if the flags are set
  383. // this is because we want to try and get the default credentials
  384. // even if the flags were set
  385. if (!_lpszUserName && !_lpszPassword) {
  386. return(TRUE);
  387. }else {
  388. return(FALSE);
  389. }
  390. }
  391. DWORD
  392. CCredentials::GetAuthFlags()
  393. {
  394. return(_dwAuthFlags);
  395. }
  396. void
  397. CCredentials::SetAuthFlags(
  398. DWORD dwAuthFlags
  399. )
  400. {
  401. _dwAuthFlags = dwAuthFlags;
  402. }