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.

520 lines
16 KiB

  1. /*++
  2. Copyright (c) 1989 - 1999 Microsoft Corporation
  3. Module Name:
  4. smbce.h
  5. Abstract:
  6. This module defines all functions, along with implementations for inline functions
  7. related to accessing the SMB connection engine
  8. --*/
  9. #ifndef _SMBCE_H_
  10. #define _SMBCE_H_
  11. //
  12. // The SMB protocol has a number of dialects. These reflect the extensions made
  13. // to the core protocol over a period of time to cater to increasingly sophisticated
  14. // file systems. The connection engine must be capable of dealing with different
  15. // dialects implemented by server. The underlying Transport mechanism is used to
  16. // uniquely identify the file server and the SMB protocol furnishes the remaining
  17. // identification information to uniquely map an SMB onto a particular file opened by
  18. // a particular client. The three important pieces of information are the SMB_TREE_ID,
  19. // SMB_FILE_ID and SMB_USER_ID. These identify the particular connection made by a
  20. // client machine, the particular file opened on that connection, and the user on
  21. // behalf of whom the file has been opened. Note that there could be multiple
  22. // connections from a client machine to a server machine. Therefore the unique id. is
  23. // really connection based rather than machine based. The SMB connection engine
  24. // data structures are built around these concepts.
  25. //
  26. // The known SMB dialects are as follows.
  27. //
  28. typedef enum _SMB_DIALECT_ {
  29. PCNET1_DIALECT,
  30. //XENIXCORE_DIALECT,
  31. //MSNET103_DIALECT,
  32. LANMAN10_DIALECT,
  33. WFW10_DIALECT,
  34. LANMAN12_DIALECT,
  35. LANMAN21_DIALECT,
  36. NTLANMAN_DIALECT
  37. } SMB_DIALECT, *PSMB_DIALECT;
  38. #define NET_ROOT_FILESYSTEM_UNKOWN ((UCHAR)0)
  39. #define NET_ROOT_FILESYSTEM_FAT ((UCHAR)1)
  40. #define NET_ROOT_FILESYSTEM_NTFS ((UCHAR)2)
  41. typedef UCHAR NET_ROOT_FILESYSTEM, *PNET_ROOT_FILESYSTEM;
  42. //
  43. // The SMBCE_NET_ROOT encapsulates the information pertaining to a share on a server.
  44. //
  45. //we restrict to the first 7 characters (HPFS386)
  46. #define SMB_MAXIMUM_SUPPORTED_VOLUME_LABEL 7
  47. #define MaximumNumberOfVNetRootContextsForScavenging 10
  48. typedef struct _SMBCE_NET_ROOT_ {
  49. BOOLEAN DfsAware;
  50. NET_ROOT_TYPE NetRootType;
  51. NET_ROOT_FILESYSTEM NetRootFileSystem;
  52. SMB_USER_ID UserId;
  53. ULONG MaximumReadBufferSize;
  54. ULONG MaximumWriteBufferSize;
  55. LIST_ENTRY ClusterSizeSerializationQueue;
  56. ULONG FileSystemAttributes;
  57. LONG MaximumComponentNameLength;
  58. UCHAR ClusterShift;
  59. BOOLEAN Disconnected;
  60. LIST_ENTRY DirNotifyList; // head of a list of notify Irps.
  61. PNOTIFY_SYNC pNotifySync; // used to synchronize the dir notify list.
  62. LIST_ENTRY NotifyeeFobxList; // list of fobx's given to the fsrtl structure
  63. FAST_MUTEX NotifyeeFobxListMutex;
  64. union {
  65. struct {
  66. USHORT FileSystemNameLength;
  67. WCHAR FileSystemName[SMB_MAXIMUM_SUPPORTED_VOLUME_LABEL];
  68. };
  69. struct {
  70. USHORT Pad2;
  71. UCHAR FileSystemNameALength;
  72. UCHAR FileSystemNameA[SMB_MAXIMUM_SUPPORTED_VOLUME_LABEL];
  73. UCHAR Pad; //this field is used for a null in a dbgprint; don't move it
  74. };
  75. };
  76. //ULONG ClusterSize;
  77. } SMBCE_NET_ROOT, *PSMBCE_NET_ROOT;
  78. //
  79. // There are two levels of security in the SMB protocol. User level security and Share level
  80. // security. Corresponding to each user in the user level security mode there is a session.
  81. //
  82. // Typically the password, user name and domain name strings associated with the session entry
  83. // revert to the default values, i.e., they are zero. In the event that they are not zero the
  84. // SessionString represents a concatenated version of the password,user name and domain name in
  85. // that order. This representation in a concatenated way yields us a savings of atleast 3
  86. // USHORT's over other representations.
  87. //
  88. typedef enum _SECURITY_MODE_ {
  89. SECURITY_MODE_SHARE_LEVEL = 0,
  90. SECURITY_MODE_USER_LEVEL = 1
  91. } SECURITY_MODE, *PSECURITY_MODE;
  92. #define SMBCE_SHARE_LEVEL_SERVER_USERID 0xffffffff
  93. typedef enum _SESSION_TYPE_ {
  94. UNINITIALIZED_SESSION,
  95. LANMAN_SESSION
  96. } SESSION_TYPE, *PSESSION_TYPE;
  97. #define SMBCE_SESSION_FLAGS_LANMAN_SESSION_KEY_USED (0x2)
  98. #define SMBCE_SESSION_FLAGS_NULL_CREDENTIALS (0x4)
  99. #define SMBCE_SESSION_FLAGS_GUEST_SESSION (0x10)
  100. #define SMBCE_SESSION_FLAGS_LOGGED_OFF (0x20)
  101. #define SMBCE_SESSION_FLAGS_MARKED_FOR_DELETION (0x40)
  102. typedef struct _SMBCE_SESSION_ {
  103. SESSION_TYPE Type;
  104. SMB_USER_ID UserId;
  105. // Flags associated with the session.
  106. ULONG Flags;
  107. LUID LogonId;
  108. PUNICODE_STRING pUserName;
  109. PUNICODE_STRING pPassword;
  110. PUNICODE_STRING pUserDomainName;
  111. UCHAR UserSessionKey[MSV1_0_USER_SESSION_KEY_LENGTH];
  112. UCHAR LanmanSessionKey[MSV1_0_LANMAN_SESSION_KEY_LENGTH];
  113. // The credential and context handles.
  114. CtxtHandle SecurityContextHandle;
  115. CredHandle CredentialHandle;
  116. ULONG SessionId;
  117. ULONG SessionKeyLength;
  118. ULONG NumberOfActiveVNetRoot;
  119. } SMBCE_SESSION, *PSMBCE_SESSION;
  120. extern VOID
  121. UninitializeSecurityContextsForSession(PSMBCE_SESSION pSession);
  122. //
  123. // SMBCE_*_SERVER -- This data structure encapsulates all the information related to a server.
  124. // Since there are multiple dialects of the SMB protocol, the capabilities as well as the
  125. // actions that need to be taken at the client machine are very different.
  126. //
  127. // Owing to the number of dialects of the SMB protocol we have two design possibilities.
  128. // Either we define an all encompassing data structure and have a code path that
  129. // uses the dialect and the capabilities of the connection to determine the action
  130. // required, or we use a subclassing mechanism associated with a dispatch vector.
  131. // The advantage of the second mechanism is that it can be developed incrementally and
  132. // it is very easily extensible. The disadvantage of this mechanism is that it can
  133. // lead to a very large footprint, if sufficient care is not exercised during
  134. // factorization and we could have lots and lots of procedure calls which has an
  135. // adverse effect on the code generated.
  136. //
  137. // We will adopt the second approach ( Thereby implicitly defining the metrics by
  138. // which the code should be evaluated !! ).
  139. //
  140. // The types of SMBCE_SERVER's can be classified in the following hierarchy
  141. //
  142. // SMBCE_SERVER
  143. //
  144. // SMBCE_USER_LEVEL_SERVER
  145. //
  146. // SMBCE_NT_SERVER
  147. //
  148. // SMBCE_SHARE_LEVEL_SERVER
  149. //
  150. // The dispatch vector which defines the set of methods supported by all the connections
  151. // (virtual functions in C++ terminology) are as follows
  152. //
  153. #define RAW_READ_CAPABILITY 0x0001
  154. #define RAW_WRITE_CAPABILITY 0x0002
  155. #define ECHO_PROBE_IDLE 0x1
  156. #define ECHO_PROBE_AWAITING_RESPONSE 0x2
  157. #define CRYPT_TEXT_LEN MSV1_0_CHALLENGE_LENGTH
  158. typedef struct _NTLANMAN_SERVER_ {
  159. ULONG NtCapabilities;
  160. } NTLANMAN_SERVER, *PNTLANMAN_SERVER;
  161. typedef struct _SMBCE_SERVER_ {
  162. // the server version count
  163. ULONG Version;
  164. // the dispatch vector
  165. struct _SMBCE_SERVER_DISPATCH_VECTOR_ *pDispatch;
  166. // the SMB dialect
  167. SMB_DIALECT Dialect;
  168. // More Server Capabilities
  169. ULONG DialectFlags;
  170. // the session key
  171. ULONG SessionKey;
  172. // the server Ip address
  173. ULONG IpAddress;
  174. // Security mode supported on the server
  175. SECURITY_MODE SecurityMode;
  176. // Time zone bias for conversion.
  177. LARGE_INTEGER TimeZoneBias;
  178. // Echo Expiry Time
  179. LARGE_INTEGER EchoExpiryTime;
  180. LONG SmbsReceivedSinceLastStrobe;
  181. LONG EchoProbeState;
  182. LONG NumberOfEchoProbesSent;
  183. // Maximum negotiated buffer size.
  184. ULONG MaximumBufferSize;
  185. // maximum buffer size for read/write operations
  186. ULONG MaximumDiskFileReadBufferSize;
  187. ULONG MaximumNonDiskFileReadBufferSize;
  188. ULONG MaximumDiskFileWriteBufferSize;
  189. ULONG MaximumNonDiskFileWriteBufferSize;
  190. // This is used to detect the number of server opens. If it is larger than 0,
  191. // we shouldn't tear down the current transport in case the user provides the transport.
  192. LONG NumberOfSrvOpens;
  193. LONG NumberOfActiveSessions;
  194. LONG NumberOfVNetRootContextsForScavenging;
  195. LONG MidCounter;
  196. // Maximum number of multiplexed requests
  197. USHORT MaximumRequests;
  198. // Maximum number of VC's
  199. USHORT MaximumVCs;
  200. // Server Capabilities
  201. USHORT Capabilities;
  202. // encrypt passwords
  203. BOOLEAN EncryptPasswords;
  204. // distinguishes a loopback connections
  205. BOOLEAN IsLoopBack;
  206. // There are certain servers that return DF_NT_SMBS in the negotiate
  207. // but do not support change notifies. This allows us to suppress
  208. // change notify requests to those servers.
  209. BOOLEAN ChangeNotifyNotSupported;
  210. // avoid multiple event logs posted for security context failures
  211. BOOLEAN EventLogPosted;
  212. USHORT EncryptionKeyLength;
  213. UCHAR EncryptionKey[CRYPT_TEXT_LEN];
  214. // Dialect specific information
  215. union {
  216. NTLANMAN_SERVER NtServer;
  217. };
  218. } SMBCE_SERVER, *PSMBCE_SERVER;
  219. typedef
  220. NTSTATUS
  221. (*PBUILD_SESSION_SETUP_SMB)(
  222. IN OUT struct _SMB_EXCHANGE *pExchange,
  223. IN OUT PGENERIC_ANDX pSmb,
  224. IN OUT PULONG pBufferSize
  225. );
  226. typedef
  227. NTSTATUS
  228. (*PBUILD_TREE_CONNECT_SMB)(
  229. IN OUT struct _SMB_EXCHANGE *pExchange,
  230. IN OUT PGENERIC_ANDX pSmb,
  231. IN OUT PULONG pBufferSize
  232. );
  233. typedef struct _SMBCE_SERVER_DISPATCH_VECTOR_ {
  234. PBUILD_SESSION_SETUP_SMB BuildSessionSetup;
  235. PBUILD_TREE_CONNECT_SMB BuildTreeConnect;
  236. } SMBCE_SERVER_DISPATCH_VECTOR, *PSMBCE_SERVER_DISPATCH_VECTOR;
  237. #define SMBCE_SERVER_DIALECT_DISPATCH(pServer,Routine,Arguments) \
  238. (*((pServer)->pDispatch->Routine))##Arguments
  239. // The SMBCE engine process all requests in an asychronous fashion. Therefore for synchronous
  240. // requests an additional mechanism is required for synchronization. The following data structure
  241. // provides an easy way for implementing this synchronization.
  242. //
  243. // NOTE: For asynchronous resumption contexts the resumption routine can be invoked
  244. // at DPC level.
  245. #define SMBCE_RESUMPTION_CONTEXT_FLAG_ASYNCHRONOUS (0x1)
  246. typedef struct SMBCE_RESUMPTION_CONTEXT {
  247. ULONG Flags;
  248. NTSTATUS Status; // the status
  249. PVOID pContext; // a void pointer for clients to add additional context information
  250. union {
  251. PRX_WORKERTHREAD_ROUTINE pRoutine; // asynchronous contexts
  252. KEVENT Event; // the event for synchronization
  253. };
  254. } SMBCE_RESUMPTION_CONTEXT, *PSMBCE_RESUMPTION_CONTEXT;
  255. #define SmbCeIsResumptionContextAsynchronous(pResumptionContext) \
  256. ((pResumptionContext)->Flags & SMBCE_RESUMPTION_CONTEXT_FLAG_ASYNCHRONOUS)
  257. INLINE VOID
  258. SmbCeInitializeResumptionContext(
  259. PSMBCE_RESUMPTION_CONTEXT pResumptionContext)
  260. {
  261. KeInitializeEvent(&(pResumptionContext)->Event,NotificationEvent,FALSE);
  262. pResumptionContext->Status = STATUS_SUCCESS;
  263. pResumptionContext->Flags = 0;
  264. pResumptionContext->pContext = NULL;
  265. }
  266. INLINE VOID
  267. SmbCeInitializeAsynchronousResumptionContext(
  268. PSMBCE_RESUMPTION_CONTEXT pResumptionContext,
  269. PRX_WORKERTHREAD_ROUTINE pResumptionRoutine,
  270. PVOID pResumptionRoutineParam)
  271. {
  272. pResumptionContext->Status = STATUS_SUCCESS;
  273. pResumptionContext->Flags = SMBCE_RESUMPTION_CONTEXT_FLAG_ASYNCHRONOUS;
  274. pResumptionContext->pContext = pResumptionRoutineParam;
  275. pResumptionContext->pRoutine = pResumptionRoutine;
  276. }
  277. INLINE VOID
  278. SmbCeSuspend(
  279. PSMBCE_RESUMPTION_CONTEXT pResumptionContext)
  280. {
  281. ASSERT(!(pResumptionContext->Flags & SMBCE_RESUMPTION_CONTEXT_FLAG_ASYNCHRONOUS));
  282. KeWaitForSingleObject(
  283. &pResumptionContext->Event,
  284. Executive,
  285. KernelMode,
  286. FALSE,
  287. NULL);
  288. }
  289. INLINE VOID
  290. SmbCeResume(
  291. PSMBCE_RESUMPTION_CONTEXT pResumptionContext)
  292. {
  293. if (!(pResumptionContext->Flags & SMBCE_RESUMPTION_CONTEXT_FLAG_ASYNCHRONOUS)) {
  294. KeSetEvent(&(pResumptionContext)->Event,0,FALSE);
  295. } else {
  296. if (RxShouldPostCompletion()) {
  297. RxDispatchToWorkerThread(
  298. MRxSmbDeviceObject,
  299. CriticalWorkQueue,
  300. pResumptionContext->pRoutine,
  301. pResumptionContext->pContext);
  302. } else {
  303. (pResumptionContext->pRoutine)(pResumptionContext->pContext);
  304. }
  305. }
  306. }
  307. //
  308. // The SMBCE_REQUEST struct encapsulates the continuation context associated. Typically
  309. // the act of sending a SMB along an exchange results in a SMBCE_REQUEST structure being
  310. // created with sufficient context information to resume the exchange upon reciept of
  311. // response from the serve. The SMBCE_REQUEST conatins ebough information to identify
  312. // the SMB for which the response is being obtained followed by enough context information
  313. // to resume the exchange.
  314. //
  315. typedef enum _SMBCE_OPERATION_ {
  316. SMBCE_TRANCEIVE,
  317. SMBCE_RECEIVE,
  318. SMBCE_SEND,
  319. SMBCE_ASYNCHRONOUS_SEND,
  320. SMBCE_ACQUIRE_MID
  321. } SMBCE_OPERATION, *PSMBCE_OPERATION;
  322. typedef enum _SMBCE_REQUEST_TYPE_ {
  323. ORDINARY_REQUEST,
  324. COPY_DATA_REQUEST,
  325. RECONNECT_REQUEST,
  326. ACQUIRE_MID_REQUEST
  327. } SMBCE_REQUEST_TYPE, *PSMBCE_REQUEST_TYPE;
  328. typedef struct _SMBCE_GENERIC_REQUEST_ {
  329. SMBCE_REQUEST_TYPE Type;
  330. // the exchange instance that originated this SMB
  331. struct _SMB_EXCHANGE * pExchange;
  332. } SMBCE_GENERIC_REQUEST, *PSMBCE_GENERIC_REQUEST;
  333. typedef struct _SMBCE_REQUEST_ {
  334. SMBCE_GENERIC_REQUEST;
  335. // the type of request
  336. SMBCE_OPERATION Operation;
  337. // the virtual circuit along which this request was sent.
  338. PRXCE_VC pVc;
  339. // MPX Id of outgoing request.
  340. SMB_MPX_ID Mid;
  341. // the pedigree of the request
  342. SMB_TREE_ID TreeId; // The Tree Id.
  343. SMB_FILE_ID FileId; // The file id.
  344. SMB_USER_ID UserId; // User Id. for cancel.
  345. SMB_PROCESS_ID ProcessId; // Process Id. for cancel.
  346. PMDL pSendBuffer;
  347. ULONG BytesSent;
  348. } SMBCE_REQUEST, *PSMBCE_REQUEST;
  349. typedef struct _SMBCE_COPY_DATA_REQUEST_ {
  350. SMBCE_GENERIC_REQUEST;
  351. // the virtual circuit along which this request was sent.
  352. PRXCE_VC pVc;
  353. // the buffer into whihc data is being copied.
  354. PVOID pBuffer;
  355. // the actual number of bytes copied
  356. ULONG BytesCopied;
  357. } SMBCE_COPY_DATA_REQUEST, *PSMBCE_COPY_DATA_REQUEST;
  358. typedef struct _SMBCE_RECONNECT_REQUEST_ {
  359. SMBCE_GENERIC_REQUEST;
  360. } SMBCE_RECONNECT_REQUEST, *PSMBCE_RECONNECT_REQUEST;
  361. typedef struct _SMBCE_MID_REQUEST_ {
  362. SMBCE_GENERIC_REQUEST;
  363. PSMBCE_RESUMPTION_CONTEXT pResumptionContext;
  364. } SMBCE_MID_REQUEST, *PSMBCE_MID_REQUEST;
  365. //
  366. // extern function declarations
  367. //
  368. extern NTSTATUS
  369. BuildSessionSetupSmb(
  370. struct _SMB_EXCHANGE *pExchange,
  371. PGENERIC_ANDX pAndXSmb,
  372. PULONG pAndXSmbBufferSize);
  373. extern NTSTATUS
  374. CoreBuildTreeConnectSmb(
  375. struct _SMB_EXCHANGE *pExchange,
  376. PGENERIC_ANDX pAndXSmb,
  377. PULONG pAndXSmbBufferSize);
  378. extern NTSTATUS
  379. LmBuildTreeConnectSmb(
  380. struct _SMB_EXCHANGE *pExchange,
  381. PGENERIC_ANDX pAndXSmb,
  382. PULONG pAndXSmbBufferSize);
  383. extern NTSTATUS
  384. NtBuildTreeConnectSmb(
  385. struct _SMB_EXCHANGE *pExchange,
  386. PGENERIC_ANDX pAndXSmb,
  387. PULONG pAndXSmbBufferSize);
  388. extern NTSTATUS
  389. BuildNegotiateSmb(
  390. PVOID *pSmbBufferPointer,
  391. PULONG pSmbBufferLength);
  392. extern NTSTATUS
  393. ParseNegotiateResponse(
  394. IN OUT struct _SMB_ADMIN_EXCHANGE_ *pExchange,
  395. IN ULONG BytesIndicated,
  396. IN ULONG BytesAvailable,
  397. OUT PULONG pBytesTaken,
  398. IN PSMB_HEADER pSmbHeader,
  399. OUT PMDL *pDataBufferPointer,
  400. OUT PULONG pDataSize);
  401. extern struct _MINIRDR_DISPATCH MRxSmbDispatch;
  402. #endif // _SMBCE_H_
  403.