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.

401 lines
14 KiB

  1. /*++ BUILD Version: 0009 // Increment this if a change has global effects
  2. Copyright (c) 1987-1993 Microsoft Corporation
  3. Module Name:
  4. sessetup.c
  5. Abstract:
  6. This module implements the Session setup related routines
  7. Author:
  8. Balan Sethu Raman (SethuR) 06-Mar-95 Created
  9. --*/
  10. #include "precomp.h"
  11. #pragma hdrstop
  12. #include <exsessup.h>
  13. #include "ntlsapi.h"
  14. #include "mrxsec.h"
  15. NTSTATUS
  16. BuildSessionSetupSecurityInformation(
  17. PSMB_EXCHANGE pExchange,
  18. PBYTE pSmbBuffer,
  19. PULONG pSmbBufferSize)
  20. /*++
  21. Routine Description:
  22. This routine builds the security related information for the session setup SMB
  23. Arguments:
  24. pServer - the server instance
  25. pSmbBuffer - the SMB buffer
  26. pSmbBufferSize - the size of the buffer on input ( modified to size remaining on
  27. output)
  28. Return Value:
  29. RXSTATUS - The return status for the operation
  30. Notes:
  31. Eventhough the genral structure of the code tries to isolate dialect specific issues
  32. as much as possible this routine takes the opposite approach. This is because of the
  33. preamble and prologue to security interaction which far outweigh the dialect specific
  34. work required to be done. Therefore in the interests of a smaller footprint this approach
  35. has been adopted.
  36. --*/
  37. {
  38. NTSTATUS Status;
  39. BOOLEAN fProcessAttached = FALSE;
  40. UNICODE_STRING UserName;
  41. UNICODE_STRING DomainName;
  42. STRING CaseSensitiveResponse;
  43. STRING CaseInsensitiveResponse;
  44. PVOID pSecurityBlob;
  45. USHORT SecurityBlobSize;
  46. PSMBCE_SERVER pServer = &pExchange->SmbCeContext.pServerEntry->Server;
  47. PSMBCE_SESSION pSession = &pExchange->SmbCeContext.pSessionEntry->Session;
  48. SECURITY_RESPONSE_CONTEXT ResponseContext;
  49. PAGED_CODE();
  50. RxDbgTrace( +1, Dbg, ("BuildSessionSetupSecurityInformation -- Entry\n"));
  51. // Attach to the redirector's FSP to allow us to call into the security impl.
  52. if (PsGetCurrentProcess() != RxGetRDBSSProcess()) {
  53. KeAttachProcess(RxGetRDBSSProcess());
  54. fProcessAttached = TRUE;
  55. }
  56. if (pServer->DialectFlags & DF_EXTENDED_SECURITY) {
  57. Status = BuildExtendedSessionSetupResponsePrologue(
  58. pExchange,
  59. &pSecurityBlob,
  60. &SecurityBlobSize,
  61. &ResponseContext);
  62. } else {
  63. Status = BuildNtLanmanResponsePrologue(
  64. pExchange,
  65. &UserName,
  66. &DomainName,
  67. &CaseSensitiveResponse,
  68. &CaseInsensitiveResponse,
  69. &ResponseContext);
  70. }
  71. if (NT_SUCCESS(Status)) {
  72. PBYTE pBuffer = pSmbBuffer;
  73. ULONG BufferSize = *pSmbBufferSize;
  74. if ((pServer->Dialect == NTLANMAN_DIALECT) &&
  75. (BooleanFlagOn(pServer->DialectFlags,DF_EXTENDED_SECURITY))) {
  76. PREQ_NT_EXTENDED_SESSION_SETUP_ANDX pExtendedNtSessionSetupReq;
  77. // Position the buffer for copying the security blob
  78. pBuffer += FIELD_OFFSET(REQ_NT_EXTENDED_SESSION_SETUP_ANDX,Buffer);
  79. BufferSize -= FIELD_OFFSET(REQ_NT_EXTENDED_SESSION_SETUP_ANDX,Buffer);
  80. pExtendedNtSessionSetupReq = (PREQ_NT_EXTENDED_SESSION_SETUP_ANDX)pSmbBuffer;
  81. SmbPutUshort(
  82. &pExtendedNtSessionSetupReq->SecurityBlobLength,
  83. SecurityBlobSize);
  84. if (BufferSize >= SecurityBlobSize) {
  85. RtlCopyMemory(
  86. pBuffer,
  87. pSecurityBlob,
  88. SecurityBlobSize);
  89. BufferSize -= SecurityBlobSize;
  90. } else {
  91. Status = STATUS_BUFFER_OVERFLOW;
  92. }
  93. } else if (pServer->Dialect == NTLANMAN_DIALECT) {
  94. PREQ_NT_SESSION_SETUP_ANDX pNtSessionSetupReq = (PREQ_NT_SESSION_SETUP_ANDX)pSmbBuffer;
  95. // It it is a NT server both the case insensitive and case sensitive passwords
  96. // need to be copied. for share-level, just copy a token 1-byte NULL password
  97. // Position the buffer for copying the password.
  98. pBuffer += FIELD_OFFSET(REQ_NT_SESSION_SETUP_ANDX,Buffer);
  99. BufferSize -= FIELD_OFFSET(REQ_NT_SESSION_SETUP_ANDX,Buffer);
  100. if (pServer->SecurityMode == SECURITY_MODE_USER_LEVEL){
  101. RxDbgTrace( 0, Dbg, ("BuildSessionSetupSecurityInformation -- NtUserPasswords\n"));
  102. SmbPutUshort(
  103. &pNtSessionSetupReq->CaseInsensitivePasswordLength,
  104. CaseInsensitiveResponse.Length);
  105. SmbPutUshort(
  106. &pNtSessionSetupReq->CaseSensitivePasswordLength,
  107. CaseSensitiveResponse.Length);
  108. Status = SmbPutString(
  109. &pBuffer,
  110. &CaseInsensitiveResponse,
  111. &BufferSize);
  112. if (NT_SUCCESS(Status)) {
  113. Status = SmbPutString(
  114. &pBuffer,
  115. &CaseSensitiveResponse,
  116. &BufferSize);
  117. }
  118. } else {
  119. RxDbgTrace( 0, Dbg, ("BuildSessionSetupSecurityInformation -- NtSharePasswords\n"));
  120. SmbPutUshort(&pNtSessionSetupReq->CaseInsensitivePasswordLength, 1);
  121. SmbPutUshort(&pNtSessionSetupReq->CaseSensitivePasswordLength, 1);
  122. *pBuffer = 0;
  123. *(pBuffer+1) = 0;
  124. pBuffer += 2;
  125. BufferSize -= 2;
  126. }
  127. } else {
  128. PREQ_SESSION_SETUP_ANDX pSessionSetupReq = (PREQ_SESSION_SETUP_ANDX)pSmbBuffer;
  129. // Position the buffer for copying the password.
  130. pBuffer += FIELD_OFFSET(REQ_SESSION_SETUP_ANDX,Buffer);
  131. BufferSize -= FIELD_OFFSET(REQ_SESSION_SETUP_ANDX,Buffer);
  132. if (pServer->SecurityMode == SECURITY_MODE_USER_LEVEL) {
  133. // For othe lanman servers only the case sensitive password is required.
  134. SmbPutUshort(
  135. &pSessionSetupReq->PasswordLength,
  136. CaseSensitiveResponse.Length);
  137. // Copy the password
  138. Status = SmbPutString(
  139. &pBuffer,
  140. &CaseSensitiveResponse,
  141. &BufferSize);
  142. } else {
  143. // Share level security. Send a null string for the password
  144. SmbPutUshort(&pSessionSetupReq->PasswordLength,1);
  145. *pBuffer++ = '\0';
  146. BufferSize -= sizeof(CHAR);
  147. }
  148. }
  149. // The User name and the domain name strings can be either copied from
  150. // the information returned in the request response or the information
  151. // that is already present in the session entry.
  152. if (NT_SUCCESS(Status) &&
  153. !BooleanFlagOn(pServer->DialectFlags,DF_EXTENDED_SECURITY)) {
  154. if ((pServer->Dialect == NTLANMAN_DIALECT) &&
  155. (pServer->NtServer.NtCapabilities & CAP_UNICODE)) {
  156. // Copy the account/domain names as UNICODE strings
  157. PBYTE pTempBuffer = pBuffer;
  158. RxDbgTrace( 0, Dbg, ("BuildSessionSetupSecurityInformation -- account/domain as unicode\n"));
  159. pBuffer = ALIGN_SMB_WSTR(pBuffer);
  160. BufferSize -= (pBuffer - pTempBuffer);
  161. Status = SmbPutUnicodeString(
  162. &pBuffer,
  163. &UserName,
  164. &BufferSize);
  165. if (NT_SUCCESS(Status)) {
  166. Status = SmbPutUnicodeString(
  167. &pBuffer,
  168. &DomainName,
  169. &BufferSize);
  170. }
  171. } else {
  172. // Copy the account/domain names as ASCII strings.
  173. RxDbgTrace( 0, Dbg, ("BuildSessionSetupSecurityInformation -- account/domain as ascii\n"));
  174. Status = SmbPutUnicodeStringAsOemString(
  175. &pBuffer,
  176. &UserName,
  177. &BufferSize);
  178. if (NT_SUCCESS(Status)) {
  179. Status = SmbPutUnicodeStringAsOemString(
  180. &pBuffer,
  181. &DomainName,
  182. &BufferSize);
  183. }
  184. }
  185. }
  186. if (NT_SUCCESS(Status)) {
  187. *pSmbBufferSize = BufferSize;
  188. }
  189. }
  190. // Free the buffer allocated by the security package.
  191. if (pServer->DialectFlags & DF_EXTENDED_SECURITY) {
  192. BuildExtendedSessionSetupResponseEpilogue(&ResponseContext);
  193. } else {
  194. BuildNtLanmanResponseEpilogue(&ResponseContext);
  195. }
  196. // Detach from the rdr process.
  197. if (fProcessAttached) {
  198. KeDetachProcess();
  199. }
  200. RxDbgTrace( -1, Dbg, ("BuildSessionSetupSecurityInformation -- Exit, status=%08lx\n",Status));
  201. return Status;
  202. }
  203. NTSTATUS
  204. BuildTreeConnectSecurityInformation(
  205. PSMB_EXCHANGE pExchange,
  206. PBYTE pBuffer,
  207. PBYTE pPasswordLength,
  208. PULONG pSmbBufferSize)
  209. /*++
  210. Routine Description:
  211. This routine builds the security related information for the session setup SMB
  212. Arguments:
  213. pServer - the server instance
  214. pLogonId - the logon id. for which the session is being setup
  215. pPassword - the user supplied password if any
  216. pBuffer - the password buffer
  217. pPasswordLength - where the password length is to be stored
  218. pSmbBufferSize - the size of the buffer on input ( modified to size remaining on
  219. output)
  220. Return Value:
  221. NTSTATUS - The return status for the operation
  222. Notes:
  223. Eventhough the genral structure of the code tries to isolate dialect specific issues
  224. as much as possible this routine takes the opposite approach. This is because of the
  225. preamble and prologue to security interaction which far outweigh the dialect specific
  226. work required to be done. Therefore in the interests of a smaller footprint this approach
  227. has been adopted.
  228. --*/
  229. {
  230. NTSTATUS FinalStatus,Status;
  231. BOOLEAN fProcessAttached = FALSE;
  232. UNICODE_STRING UserName,DomainName;
  233. STRING CaseSensitiveChallengeResponse,CaseInsensitiveChallengeResponse;
  234. SECURITY_RESPONSE_CONTEXT ResponseContext;
  235. ULONG PasswordLength = 0;
  236. PSMBCE_SERVER pServer = &pExchange->SmbCeContext.pServerEntry->Server;
  237. PSMBCE_SESSION pSession = &pExchange->SmbCeContext.pSessionEntry->Session;
  238. PAGED_CODE();
  239. Status = STATUS_SUCCESS;
  240. if (pServer->EncryptPasswords) {
  241. // Attach to the redirector's FSP to allow us to call into the securiy impl.
  242. if (PsGetCurrentProcess() != RxGetRDBSSProcess()) {
  243. KeAttachProcess(RxGetRDBSSProcess());
  244. fProcessAttached = TRUE;
  245. }
  246. Status = BuildNtLanmanResponsePrologue(
  247. pExchange,
  248. &UserName,
  249. &DomainName,
  250. &CaseSensitiveChallengeResponse,
  251. &CaseInsensitiveChallengeResponse,
  252. &ResponseContext);
  253. if (NT_SUCCESS(Status)) {
  254. if (FlagOn(pServer->DialectFlags,DF_MIXEDCASEPW)) {
  255. RxDbgTrace( 0, Dbg, ("BuildTreeConnectSecurityInformation -- case sensitive password\n"));
  256. // Copy the password length onto the SMB buffer
  257. PasswordLength = CaseSensitiveChallengeResponse.Length;
  258. // Copy the password
  259. Status = SmbPutString(
  260. &pBuffer,
  261. &CaseSensitiveChallengeResponse,
  262. pSmbBufferSize);
  263. } else {
  264. RxDbgTrace( 0, Dbg, ("BuildTreeConnectSecurityInformation -- case insensitive password\n"));
  265. // Copy the password length onto the SMB buffer
  266. PasswordLength = CaseInsensitiveChallengeResponse.Length;
  267. // Copy the password
  268. Status = SmbPutString(
  269. &pBuffer,
  270. &CaseInsensitiveChallengeResponse,
  271. pSmbBufferSize);
  272. }
  273. BuildNtLanmanResponseEpilogue(&ResponseContext);
  274. }
  275. if (fProcessAttached) {
  276. KeDetachProcess();
  277. }
  278. } else {
  279. if (pSession->pPassword == NULL) {
  280. // The logon password cannot be sent as plain text. Send a single blank as password.
  281. PasswordLength = 2;
  282. if (*pSmbBufferSize >= 2) {
  283. *((PCHAR)pBuffer) = ' ';
  284. pBuffer += sizeof(CHAR);
  285. *((PCHAR)pBuffer) = '\0';
  286. pBuffer += sizeof(CHAR);
  287. Status = STATUS_SUCCESS;
  288. } else {
  289. Status = STATUS_BUFFER_OVERFLOW;
  290. }
  291. } else {
  292. OEM_STRING OemString;
  293. OemString.Length = OemString.MaximumLength = (USHORT)(*pSmbBufferSize - sizeof(CHAR));
  294. OemString.Buffer = pBuffer;
  295. Status = RtlUnicodeStringToOemString(
  296. &OemString,
  297. pSession->pPassword,
  298. FALSE);
  299. if (NT_SUCCESS(Status)) {
  300. PasswordLength = OemString.Length+1;
  301. }
  302. }
  303. // reduce the byte count
  304. *pSmbBufferSize -= PasswordLength;
  305. }
  306. SmbPutUshort(pPasswordLength,(USHORT)PasswordLength);
  307. return Status;
  308. }
  309.