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.

305 lines
8.1 KiB

  1. #ifndef MAC
  2. #include <security.h>
  3. #endif
  4. #include <bootdefs.h>
  5. #include <sspi.h>
  6. #include <ntlmsspi.h>
  7. #include <crypt.h>
  8. #include <cred.h>
  9. #include <winerror.h>
  10. #include "cache.h"
  11. #ifndef MAC
  12. #include <rpc.h>
  13. #endif
  14. #define toupper(_c) ( ((_c) >= 'a' && (_c) <= 'z') ? ( (_c)-'a'+'A' ) : (_c) )
  15. BOOL
  16. SspGetWorkstation(
  17. PSSP_CREDENTIAL Credential
  18. );
  19. static PSSP_CREDENTIAL Cache = NULL;
  20. void
  21. CacheInitializeCache(
  22. )
  23. {
  24. }
  25. BOOL
  26. CacheGetPassword(
  27. PSSP_CREDENTIAL Credential
  28. )
  29. {
  30. if (Cache == NULL) {
  31. return (FALSE);
  32. }
  33. #ifdef BL_USE_LM_PASSWORD
  34. Credential->LmPassword = SspAlloc (sizeof(LM_OWF_PASSWORD));
  35. if (Credential->LmPassword == NULL) {
  36. return (FALSE);
  37. }
  38. #endif
  39. Credential->NtPassword = (LM_OWF_PASSWORD*)SspAlloc (sizeof(NT_OWF_PASSWORD));
  40. if (Credential->NtPassword == NULL) {
  41. return (FALSE);
  42. }
  43. #ifdef BL_USE_LM_PASSWORD
  44. _fmemcpy((PCHAR)Credential->LmPassword, (PCHAR)Cache->LmPassword, sizeof(LM_OWF_PASSWORD));
  45. #endif
  46. _fmemcpy((PCHAR)Credential->NtPassword, (PCHAR)Cache->NtPassword, sizeof(NT_OWF_PASSWORD));
  47. return (TRUE);
  48. }
  49. SECURITY_STATUS
  50. CacheSetCredentials(
  51. IN PVOID AuthData,
  52. PSSP_CREDENTIAL Credential
  53. )
  54. {
  55. SEC_WINNT_AUTH_IDENTITY *Identity = (SEC_WINNT_AUTH_IDENTITY*)AuthData;
  56. char TmpText[CLEAR_BLOCK_LENGTH*2];
  57. NT_PASSWORD TmpNtPassword;
  58. WCHAR TmpUnicodeText[CLEAR_BLOCK_LENGTH*2];
  59. int Length = 0;
  60. int i = 0;
  61. if (Identity->Domain == NULL)
  62. return SEC_E_UNKNOWN_CREDENTIALS;
  63. Credential->Username = NULL;
  64. Credential->Domain = NULL;
  65. #ifdef BL_USE_LM_PASSWORD
  66. Credential->LmPassword = NULL;
  67. #endif
  68. Credential->NtPassword = NULL;
  69. Credential->Workstation = NULL;
  70. // If no identity is passed and there is no cached identity, give up.
  71. if (AuthData == NULL)
  72. {
  73. if (Cache == NULL)
  74. return SEC_E_UNKNOWN_CREDENTIALS;
  75. }
  76. // Save the latest authentication information.
  77. else
  78. {
  79. // If an old cache entry exists, release its strings.
  80. if (Cache != NULL)
  81. {
  82. if (Cache->Username != NULL)
  83. SspFree(Cache->Username);
  84. if (Cache->Domain != NULL)
  85. SspFree(Cache->Domain);
  86. if (Cache->Workstation != NULL)
  87. SspFree(Cache->Workstation);
  88. #ifdef BL_USE_LM_PASSWORD
  89. if (Cache->LmPassword != NULL)
  90. SspFree(Cache->LmPassword);
  91. #endif
  92. if (Cache->NtPassword != NULL)
  93. SspFree(Cache->NtPassword);
  94. }
  95. // Otherwise, allocate a cache entry
  96. else
  97. {
  98. Cache = (PSSP_CREDENTIAL) SspAlloc (sizeof(SSP_CREDENTIAL));
  99. if (Cache == NULL) {
  100. return (SEC_E_INSUFFICIENT_MEMORY);
  101. }
  102. }
  103. Cache->Username = NULL;
  104. Cache->Domain = NULL;
  105. #ifdef BL_USE_LM_PASSWORD
  106. Cache->LmPassword = NULL;
  107. #endif
  108. Cache->NtPassword = NULL;
  109. Cache->Workstation = NULL;
  110. Cache->Username = (PCHAR)SspAlloc(_fstrlen((const char*)Identity->User) + 1);
  111. if (Cache->Username == NULL) {
  112. goto cache_failure;
  113. }
  114. _fstrcpy(Cache->Username, (const char*)Identity->User);
  115. Cache->Domain = (PCHAR)SspAlloc(_fstrlen((const char*)Identity->Domain) + 1);
  116. if (Cache->Domain == NULL) {
  117. goto cache_failure;
  118. }
  119. _fstrcpy(Cache->Domain, (const char*)Identity->Domain);
  120. // If netbios won't tell us the workstation name, make one up.
  121. if (!SspGetWorkstation(Cache))
  122. {
  123. Cache->Workstation = (PCHAR)SspAlloc(_fstrlen("none") + 1);
  124. if (Cache->Workstation == NULL) {
  125. goto cache_failure;
  126. }
  127. _fstrcpy(Cache->Workstation, "none");
  128. }
  129. #ifdef BL_USE_LM_PASSWORD
  130. Cache->LmPassword = SspAlloc (sizeof(LM_OWF_PASSWORD));
  131. if (Cache->LmPassword == NULL) {
  132. goto cache_failure;
  133. }
  134. #endif
  135. Cache->NtPassword = (LM_OWF_PASSWORD*)SspAlloc (sizeof(NT_OWF_PASSWORD));
  136. if (Cache->NtPassword == NULL) {
  137. goto cache_failure;
  138. }
  139. #ifdef ALLOW_NON_OWF_PASSWORD
  140. if ( (Credential->CredentialUseFlags & SECPKG_CRED_OWF_PASSWORD) == 0 ) {
  141. if (Identity->Password == NULL)
  142. Length = 0;
  143. else
  144. Length = _fstrlen(Identity->Password);
  145. if (Length > CLEAR_BLOCK_LENGTH * 2)
  146. goto cache_failure;
  147. // Allow NULL and "\0" passwords by prefilling TmpText with and
  148. // empty string.
  149. if (Length == 0)
  150. TmpText[0] = 0;
  151. else
  152. for (i = 0; i <= Length; i++) {
  153. TmpText[i] = toupper(Identity->Password[i]);
  154. TmpUnicodeText[i] = (WCHAR)(Identity->Password[i]);
  155. }
  156. #ifdef BL_USE_LM_PASSWORD
  157. CalculateLmOwfPassword((PLM_PASSWORD)TmpText, Cache->LmPassword);
  158. #endif
  159. TmpNtPassword.Buffer = TmpUnicodeText;
  160. TmpNtPassword.Length = Length * sizeof(WCHAR);
  161. TmpNtPassword.MaximumLength = sizeof(TmpUnicodeText);
  162. CalculateNtOwfPassword(&TmpNtPassword, Cache->NtPassword);
  163. } else
  164. #endif
  165. {
  166. //
  167. // In this case the passed-in password is the LM and NT OWF
  168. // passwords concatenated together.
  169. //
  170. #ifdef BL_USE_LM_PASSWORD
  171. _fmemcpy(Cache->LmPassword, Identity->Password, sizeof(LM_OWF_PASSWORD));
  172. #endif
  173. _fmemcpy(Cache->NtPassword, Identity->Password + sizeof(LM_OWF_PASSWORD), sizeof(NT_OWF_PASSWORD));
  174. }
  175. }
  176. // Copy the credentials for the caller.
  177. Credential->Username = (PCHAR)SspAlloc(_fstrlen(Cache->Username) + 1);
  178. if (Credential->Username == NULL) {
  179. goto out_failure;
  180. }
  181. _fstrcpy(Credential->Username, Cache->Username);
  182. if (_fstrcmp(Cache->Domain, "WORKGROUP") != 0) {
  183. Credential->Domain = (PCHAR)SspAlloc(_fstrlen(Cache->Domain) + 1);
  184. if (Credential->Domain == NULL) {
  185. goto out_failure;
  186. }
  187. _fstrcpy(Credential->Domain, Cache->Domain);
  188. }
  189. Credential->Workstation = (PCHAR)SspAlloc(_fstrlen(Cache->Workstation) + 1);
  190. if (Credential->Workstation == NULL) {
  191. goto out_failure;
  192. }
  193. _fstrcpy(Credential->Workstation, Cache->Workstation);
  194. #ifdef BL_USE_LM_PASSWORD
  195. Credential->LmPassword = SspAlloc(sizeof(LM_OWF_PASSWORD));
  196. if (Credential->LmPassword == NULL) {
  197. goto out_failure;
  198. }
  199. _fmemcpy(Credential->LmPassword, Cache->LmPassword, sizeof(LM_OWF_PASSWORD));
  200. #endif
  201. Credential->NtPassword = (LM_OWF_PASSWORD*)SspAlloc(sizeof(NT_OWF_PASSWORD));
  202. if (Credential->NtPassword == NULL) {
  203. goto out_failure;
  204. }
  205. _fmemcpy(Credential->NtPassword, Cache->NtPassword, sizeof(NT_OWF_PASSWORD));
  206. return (SEC_E_OK);
  207. cache_failure:
  208. if (Cache->Username != NULL) {
  209. SspFree(Cache->Username);
  210. }
  211. if (Cache->Domain != NULL) {
  212. SspFree(Cache->Domain);
  213. }
  214. if (Cache->Workstation != NULL) {
  215. SspFree(Cache->Workstation);
  216. }
  217. #ifdef BL_USE_LM_PASSWORD
  218. if (Cache->LmPassword != NULL) {
  219. SspFree(Cache->LmPassword);
  220. }
  221. #endif
  222. if (Cache->NtPassword != NULL) {
  223. SspFree(Cache->NtPassword);
  224. }
  225. SspFree(Cache);
  226. Cache = NULL;
  227. out_failure:
  228. if (Credential->Username != NULL) {
  229. SspFree(Credential->Username);
  230. Credential->Username = NULL;
  231. }
  232. if (Credential->Domain != NULL) {
  233. SspFree(Credential->Domain);
  234. Credential->Domain = NULL;
  235. }
  236. if (Credential->Workstation != NULL) {
  237. SspFree(Credential->Workstation);
  238. Credential->Workstation = NULL;
  239. }
  240. #ifdef BL_USE_LM_PASSWORD
  241. if (Credential->LmPassword != NULL) {
  242. SspFree(Credential->LmPassword);
  243. Credential->LmPassword = NULL;
  244. }
  245. #endif
  246. if (Credential->NtPassword != NULL) {
  247. SspFree(Credential->NtPassword);
  248. Credential->NtPassword = NULL;
  249. }
  250. return (SEC_E_INSUFFICIENT_MEMORY);
  251. }