Source code of Windows XP (NT5)
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.

581 lines
18 KiB

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