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.

535 lines
15 KiB

  1. /*++
  2. Copyright (c) 1989-2001 Microsoft Corporation
  3. Module Name:
  4. init.c
  5. Abstract:
  6. Initialization
  7. Author:
  8. Jiandong Ruan
  9. Revision History:
  10. --*/
  11. #include "precomp.h"
  12. #include "init.tmh"
  13. #ifdef ALLOC_PRAGMA
  14. #pragma alloc_text(INIT, SmbInitRegistry)
  15. #pragma alloc_text(PAGE, SmbShutdownRegistry)
  16. #pragma alloc_text(PAGE, SmbInitTdi)
  17. #pragma alloc_text(PAGE, SmbShutdownTdi)
  18. #pragma alloc_text(INIT, SmbCreateSmbDevice)
  19. #pragma alloc_text(PAGE, SmbDestroySmbDevice)
  20. #endif
  21. NTSTATUS
  22. SmbInitRegistry(
  23. IN PUNICODE_STRING RegistryPath
  24. )
  25. {
  26. OBJECT_ATTRIBUTES ObAttr;
  27. NTSTATUS status;
  28. HANDLE hKey = NULL;
  29. UNICODE_STRING uncParams;
  30. ULONG Disposition;
  31. PAGED_CODE();
  32. InitializeObjectAttributes (
  33. &ObAttr,
  34. RegistryPath,
  35. OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
  36. NULL,
  37. NULL
  38. );
  39. status = ZwOpenKey (
  40. &hKey,
  41. KEY_READ | KEY_WRITE,
  42. &ObAttr
  43. );
  44. BAIL_OUT_ON_ERROR(status);
  45. RtlInitUnicodeString(&uncParams, L"Parameters");
  46. InitializeObjectAttributes (
  47. &ObAttr,
  48. &uncParams,
  49. OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
  50. hKey,
  51. NULL
  52. );
  53. status = ZwCreateKey(
  54. &SmbCfg.ParametersKey,
  55. KEY_READ | KEY_WRITE,
  56. &ObAttr,
  57. 0,
  58. NULL,
  59. 0,
  60. &Disposition
  61. );
  62. BAIL_OUT_ON_ERROR(status);
  63. RtlInitUnicodeString(&uncParams, L"Linkage");
  64. InitializeObjectAttributes (
  65. &ObAttr,
  66. &uncParams,
  67. OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
  68. hKey,
  69. NULL
  70. );
  71. status = ZwCreateKey(
  72. &SmbCfg.LinkageKey,
  73. KEY_READ | KEY_WRITE,
  74. &ObAttr,
  75. 0,
  76. NULL,
  77. 0,
  78. &Disposition
  79. );
  80. BAIL_OUT_ON_ERROR(status);
  81. ZwClose(hKey);
  82. hKey = NULL;
  83. return status;
  84. cleanup:
  85. if (SmbCfg.LinkageKey) {
  86. ZwClose(SmbCfg.LinkageKey);
  87. SmbCfg.LinkageKey = NULL;
  88. }
  89. if (SmbCfg.ParametersKey) {
  90. ZwClose(SmbCfg.ParametersKey);
  91. SmbCfg.ParametersKey = NULL;
  92. }
  93. if (hKey) {
  94. ZwClose(hKey);
  95. }
  96. SmbTrace(SMB_TRACE_ERRORS, ("returns %!status!", status));
  97. return status;
  98. }
  99. VOID
  100. SmbShutdownRegistry(
  101. VOID
  102. )
  103. {
  104. PAGED_CODE();
  105. if (SmbCfg.ParametersKey) {
  106. ZwClose(SmbCfg.ParametersKey);
  107. SmbCfg.ParametersKey = NULL;
  108. }
  109. if (SmbCfg.LinkageKey) {
  110. ZwClose(SmbCfg.LinkageKey);
  111. SmbCfg.LinkageKey = NULL;
  112. }
  113. }
  114. #ifdef STANDALONE_SMB
  115. NTSTATUS
  116. SmbInitTdi(
  117. VOID
  118. )
  119. {
  120. UNICODE_STRING ucSmbClientName;
  121. UNICODE_STRING ucSmbProviderName;
  122. TDI_CLIENT_INTERFACE_INFO TdiClientInterface;
  123. NTSTATUS status;
  124. PAGED_CODE();
  125. RtlInitUnicodeString(&ucSmbProviderName, WC_SMB_TDI_PROVIDER_NAME);
  126. status = TdiRegisterProvider (&ucSmbProviderName, &SmbCfg.TdiProviderHandle);
  127. if (NT_SUCCESS (status)) {
  128. //
  129. // Register our Handlers with TDI
  130. //
  131. RtlInitUnicodeString(&ucSmbClientName, WC_SMB_TDI_CLIENT_NAME);
  132. RtlZeroMemory(&TdiClientInterface, sizeof(TdiClientInterface));
  133. TdiClientInterface.MajorTdiVersion = MAJOR_TDI_VERSION;
  134. TdiClientInterface.MinorTdiVersion = MINOR_TDI_VERSION;
  135. TdiClientInterface.ClientName = &ucSmbClientName;
  136. TdiClientInterface.AddAddressHandlerV2 = SmbAddressArrival;
  137. TdiClientInterface.DelAddressHandlerV2 = SmbAddressDeletion;
  138. TdiClientInterface.BindingHandler = SmbBindHandler;
  139. TdiClientInterface.PnPPowerHandler = NULL;
  140. status = TdiRegisterPnPHandlers (&TdiClientInterface, sizeof(TdiClientInterface), &SmbCfg.TdiClientHandle);
  141. if (!NT_SUCCESS (status)) {
  142. TdiDeregisterProvider (SmbCfg.TdiProviderHandle);
  143. SmbCfg.TdiProviderHandle = NULL;
  144. }
  145. }
  146. return status;
  147. }
  148. VOID
  149. SmbShutdownTdi(
  150. VOID
  151. )
  152. {
  153. NTSTATUS status;
  154. PAGED_CODE();
  155. if (SmbCfg.TdiClientHandle) {
  156. status = TdiDeregisterPnPHandlers(SmbCfg.TdiClientHandle);
  157. SmbCfg.TdiClientHandle = NULL;
  158. }
  159. if (SmbCfg.TdiProviderHandle) {
  160. status = TdiDeregisterProvider(SmbCfg.TdiProviderHandle);
  161. SmbCfg.TdiProviderHandle = NULL;
  162. }
  163. }
  164. #else
  165. VOID
  166. SmbSetTdiHandles(
  167. HANDLE ProviderHandle,
  168. HANDLE ClientHandle
  169. )
  170. {
  171. SmbCfg.TdiClientHandle = ClientHandle;
  172. SmbCfg.TdiProviderHandle = ProviderHandle;
  173. }
  174. #endif
  175. NTSTATUS
  176. SmbBuildDeviceAcl(
  177. OUT PACL * DeviceAcl
  178. )
  179. /*++
  180. Routine Description:
  181. (Lifted from SMB - SmbBuildDeviceAcl)
  182. This routine builds an ACL which gives Administrators, LocalService and NetworkService
  183. principals full access. All other principals have no access.
  184. Arguments:
  185. DeviceAcl - Output pointer to the new ACL.
  186. Return Value:
  187. STATUS_SUCCESS or an appropriate error code.
  188. --*/
  189. {
  190. PGENERIC_MAPPING GenericMapping;
  191. PSID AdminsSid, ServiceSid, NetworkSid;
  192. ULONG AclLength;
  193. NTSTATUS Status;
  194. ACCESS_MASK AccessMask = GENERIC_ALL;
  195. PACL NewAcl;
  196. //
  197. // Enable access to all the globally defined SIDs
  198. //
  199. GenericMapping = IoGetFileObjectGenericMapping();
  200. RtlMapGenericMask(&AccessMask, GenericMapping);
  201. AdminsSid = SeExports->SeAliasAdminsSid;
  202. ServiceSid = SeExports->SeLocalServiceSid;
  203. NetworkSid = SeExports->SeNetworkServiceSid;
  204. AclLength = sizeof(ACL) +
  205. 3 * sizeof(ACCESS_ALLOWED_ACE) +
  206. RtlLengthSid(AdminsSid) +
  207. RtlLengthSid(ServiceSid) +
  208. RtlLengthSid(NetworkSid) -
  209. 3 * sizeof(ULONG);
  210. NewAcl = ExAllocatePoolWithTag(PagedPool, AclLength, 'ABMS');
  211. if (NewAcl == NULL) {
  212. return (STATUS_INSUFFICIENT_RESOURCES);
  213. }
  214. Status = RtlCreateAcl(NewAcl, AclLength, ACL_REVISION);
  215. if (!NT_SUCCESS(Status)) {
  216. ExFreePool(NewAcl);
  217. return (Status);
  218. }
  219. Status = RtlAddAccessAllowedAce(
  220. NewAcl,
  221. ACL_REVISION2,
  222. AccessMask,
  223. AdminsSid
  224. );
  225. ASSERT(NT_SUCCESS(Status));
  226. if (!NT_SUCCESS(Status)) {
  227. ExFreePool(NewAcl);
  228. return (Status);
  229. }
  230. Status = RtlAddAccessAllowedAce(
  231. NewAcl,
  232. ACL_REVISION2,
  233. AccessMask,
  234. ServiceSid
  235. );
  236. ASSERT(NT_SUCCESS(Status));
  237. if (!NT_SUCCESS(Status)) {
  238. ExFreePool(NewAcl);
  239. return (Status);
  240. }
  241. Status = RtlAddAccessAllowedAce(
  242. NewAcl,
  243. ACL_REVISION2,
  244. AccessMask,
  245. NetworkSid
  246. );
  247. ASSERT(NT_SUCCESS(Status));
  248. if (!NT_SUCCESS(Status)) {
  249. ExFreePool(NewAcl);
  250. return (Status);
  251. }
  252. *DeviceAcl = NewAcl;
  253. return (STATUS_SUCCESS);
  254. }
  255. NTSTATUS
  256. SmbCreateAdminSecurityDescriptor(PDEVICE_OBJECT dev)
  257. /*++
  258. Routine Description:
  259. (Lifted from NETBT - SmbCreateAdminSecurityDescriptor)
  260. This routine creates a security descriptor which gives access
  261. only to Administrtors and LocalService. This descriptor is used
  262. to access check raw endpoint opens and exclisive access to transport
  263. addresses.
  264. Arguments:
  265. None.
  266. Return Value:
  267. STATUS_SUCCESS or an appropriate error code.
  268. --*/
  269. {
  270. PACL rawAcl = NULL;
  271. NTSTATUS status;
  272. CHAR buffer[SECURITY_DESCRIPTOR_MIN_LENGTH];
  273. PSECURITY_DESCRIPTOR localSecurityDescriptor = (PSECURITY_DESCRIPTOR) buffer;
  274. SECURITY_INFORMATION securityInformation = DACL_SECURITY_INFORMATION;
  275. //
  276. // Build a local security descriptor with an ACL giving only
  277. // administrators and service access.
  278. //
  279. status = SmbBuildDeviceAcl(&rawAcl);
  280. if (!NT_SUCCESS(status)) {
  281. SmbPrint(SMB_TRACE_PNP, ("SMB: Unable to create Raw ACL, error: 0x%08lx\n", status));
  282. return (status);
  283. }
  284. (VOID) RtlCreateSecurityDescriptor(
  285. localSecurityDescriptor,
  286. SECURITY_DESCRIPTOR_REVISION
  287. );
  288. (VOID) RtlSetDaclSecurityDescriptor(
  289. localSecurityDescriptor,
  290. TRUE,
  291. rawAcl,
  292. FALSE
  293. );
  294. //
  295. // Now apply the local descriptor to the raw descriptor.
  296. //
  297. status = SeSetSecurityDescriptorInfo(
  298. NULL,
  299. &securityInformation,
  300. localSecurityDescriptor,
  301. &dev->SecurityDescriptor,
  302. PagedPool,
  303. IoGetFileObjectGenericMapping()
  304. );
  305. if (!NT_SUCCESS(status)) {
  306. SmbPrint(SMB_TRACE_PNP, ("SMB: SeSetSecurity failed: 0x%08lx\n", status));
  307. }
  308. ExFreePool(rawAcl);
  309. return (status);
  310. }
  311. NTSTATUS
  312. SmbCreateSmbDevice(
  313. PSMB_DEVICE *ppDevice,
  314. USHORT Port,
  315. UCHAR EndpointName[NETBIOS_NAME_SIZE]
  316. )
  317. {
  318. PSMB_DEVICE DeviceObject;
  319. NTSTATUS status;
  320. UNICODE_STRING ExportName, ucName;
  321. DeviceObject = NULL;
  322. *ppDevice = NULL;
  323. RtlInitUnicodeString(&ExportName, DD_SMB6_EXPORT_NAME);
  324. status = IoCreateDevice(
  325. SmbCfg.DriverObject,
  326. sizeof(SMB_DEVICE) - sizeof(DEVICE_OBJECT),
  327. &ExportName,
  328. FILE_DEVICE_NETWORK,
  329. FILE_DEVICE_SECURE_OPEN,
  330. FALSE,
  331. (PDEVICE_OBJECT*)&DeviceObject
  332. );
  333. BAIL_OUT_ON_ERROR(status);
  334. DeviceObject->Tag = TAG_SMB6_DEVICE;
  335. KeInitializeSpinLock(&DeviceObject->Lock);
  336. InitializeListHead(&DeviceObject->UnassociatedConnectionList);
  337. InitializeListHead(&DeviceObject->ClientList);
  338. InitializeListHead(&DeviceObject->PendingDeleteConnectionList);
  339. InitializeListHead(&DeviceObject->PendingDeleteClientList);
  340. DeviceObject->ClientBinding = NULL;
  341. DeviceObject->ServerBinding = NULL;
  342. //
  343. // initialization for FIN attack protection
  344. //
  345. DeviceObject->FinAttackProtectionMode = FALSE;
  346. DeviceObject->LeaveFAPM = SmbReadLong (SmbCfg.ParametersKey, SMB_REG_LEAVE_FAPM, 50, 5);
  347. DeviceObject->EnterFAPM = SmbReadLong (SmbCfg.ParametersKey, SMB_REG_ENTER_FAPM,
  348. 400, DeviceObject->LeaveFAPM + 50);
  349. ASSERT(DeviceObject->EnterFAPM > DeviceObject->LeaveFAPM);
  350. if (DeviceObject->LeaveFAPM >= DeviceObject->EnterFAPM) {
  351. DeviceObject->EnterFAPM = 2 * DeviceObject->LeaveFAPM;
  352. }
  353. if (DeviceObject->LeaveFAPM >= DeviceObject->EnterFAPM) {
  354. //
  355. // This means overflow above
  356. //
  357. DeviceObject->LeaveFAPM = 50;
  358. DeviceObject->EnterFAPM = 400;
  359. }
  360. //
  361. // initialization for synch attack protection
  362. //
  363. DeviceObject->MaxBackLog = SmbReadLong(SmbCfg.ParametersKey, L"MaxBackLog", 1000, 100);
  364. InitializeListHead(&DeviceObject->DelayedDisconnectList);
  365. InitializeListHead(&DeviceObject->DelayedDisconnectList);
  366. InitializeListHead(&DeviceObject->PendingDisconnectList);
  367. DeviceObject->PendingDisconnectListNumber = 0;
  368. KeInitializeEvent(&DeviceObject->PendingDisconnectListEmptyEvent,
  369. NotificationEvent, TRUE);
  370. DeviceObject->DisconnectWorkerRunning = FALSE;
  371. DeviceObject->ConnectionPoolWorkerQueued = FALSE;
  372. DeviceObject->SmbServer = NULL;
  373. RtlCopyMemory(DeviceObject->EndpointName, EndpointName, NETBIOS_NAME_SIZE);
  374. ASSERT(DeviceObject->EndpointName[NETBIOS_NAME_SIZE-1] == 0x20);
  375. DeviceObject->Port = Port;
  376. SmbCfg.Tcp4Available = FALSE;
  377. SmbCfg.Tcp6Available = FALSE;
  378. SmbCreateAdminSecurityDescriptor(&DeviceObject->DeviceObject);
  379. *ppDevice = DeviceObject;
  380. return status;
  381. cleanup:
  382. if (DeviceObject) {
  383. if (SmbCfg.Tcp4Available) {
  384. SmbShutdownTCP(&DeviceObject->Tcp4);
  385. SmbCfg.Tcp4Available = FALSE;
  386. }
  387. if (SmbCfg.Tcp6Available) {
  388. SmbShutdownTCP(&DeviceObject->Tcp6);
  389. SmbCfg.Tcp6Available = FALSE;
  390. }
  391. IoDeleteDevice((PDEVICE_OBJECT)DeviceObject);
  392. }
  393. return status;
  394. }
  395. NTSTATUS
  396. SmbDestroySmbDevice(
  397. PSMB_DEVICE pDevice
  398. )
  399. {
  400. NTSTATUS status = STATUS_SUCCESS;
  401. PAGED_CODE();
  402. ASSERT(SmbCfg.Unloading);
  403. if (NULL == pDevice) {
  404. return STATUS_SUCCESS;
  405. }
  406. SmbTdiDeregister(pDevice);
  407. status = KeWaitForSingleObject(
  408. &pDevice->PendingDisconnectListEmptyEvent,
  409. Executive,
  410. KernelMode,
  411. FALSE,
  412. NULL
  413. );
  414. ASSERT(status == STATUS_WAIT_0);
  415. ASSERT(IsListEmpty(&pDevice->DelayedDisconnectList));
  416. ASSERT(IsListEmpty(&pDevice->PendingDisconnectList) && pDevice->PendingDisconnectListNumber == 0);
  417. ASSERT(IsListEmpty(&pDevice->PendingDeleteConnectionList));
  418. ASSERT(IsListEmpty(&pDevice->PendingDeleteClientList));
  419. if (SmbCfg.Tcp4Available) {
  420. status = SmbShutdownTCP(&pDevice->Tcp4);
  421. ASSERT(status == STATUS_SUCCESS);
  422. SmbCfg.Tcp4Available = FALSE;
  423. }
  424. if (SmbCfg.Tcp6Available) {
  425. status = SmbShutdownTCP(&pDevice->Tcp6);
  426. ASSERT(status == STATUS_SUCCESS);
  427. SmbCfg.Tcp6Available = FALSE;
  428. }
  429. ASSERT(status == STATUS_SUCCESS);
  430. SmbShutdownPnP();
  431. if (pDevice->ClientBinding) {
  432. ExFreePool(pDevice->ClientBinding);
  433. pDevice->ClientBinding = NULL;
  434. }
  435. if (pDevice->ServerBinding) {
  436. ExFreePool(pDevice->ServerBinding);
  437. pDevice->ServerBinding = NULL;
  438. }
  439. IoDeleteDevice((PDEVICE_OBJECT)pDevice);
  440. return STATUS_SUCCESS;
  441. }