TreeConnectHelper.cs 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. /* Copyright (C) 2014-2017 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
  2. *
  3. * You can redistribute this program and/or modify it under the terms of
  4. * the GNU Lesser Public License as published by the Free Software Foundation,
  5. * either version 3 of the License, or (at your option) any later version.
  6. */
  7. using System;
  8. using System.Collections.Generic;
  9. using System.Text;
  10. using SMBLibrary.SMB1;
  11. using Utilities;
  12. namespace SMBLibrary.Server.SMB1
  13. {
  14. internal class TreeConnectHelper
  15. {
  16. internal static SMB1Command GetTreeConnectResponse(SMB1Header header, TreeConnectAndXRequest request, SMB1ConnectionState state, NamedPipeShare services, SMBShareCollection shares)
  17. {
  18. SMB1Session session = state.GetSession(header.UID);
  19. bool isExtended = (request.Flags & TreeConnectFlags.ExtendedResponse) > 0;
  20. string shareName = ServerPathUtils.GetShareName(request.Path);
  21. ISMBShare share;
  22. ServiceName serviceName;
  23. OptionalSupportFlags supportFlags;
  24. if (String.Equals(shareName, NamedPipeShare.NamedPipeShareName, StringComparison.InvariantCultureIgnoreCase))
  25. {
  26. share = services;
  27. serviceName = ServiceName.NamedPipe;
  28. supportFlags = OptionalSupportFlags.SMB_SUPPORT_SEARCH_BITS | OptionalSupportFlags.SMB_CSC_NO_CACHING;
  29. }
  30. else
  31. {
  32. share = shares.GetShareFromName(shareName);
  33. serviceName = ServiceName.DiskShare;
  34. supportFlags = OptionalSupportFlags.SMB_SUPPORT_SEARCH_BITS | OptionalSupportFlags.SMB_CSC_CACHE_MANUAL_REINT;
  35. if (share == null)
  36. {
  37. header.Status = NTStatus.STATUS_OBJECT_PATH_NOT_FOUND;
  38. return new ErrorResponse(request.CommandName);
  39. }
  40. if (!((FileSystemShare)share).HasReadAccess(session.SecurityContext, @"\"))
  41. {
  42. header.Status = NTStatus.STATUS_ACCESS_DENIED;
  43. return new ErrorResponse(request.CommandName);
  44. }
  45. }
  46. ushort? treeID = session.AddConnectedTree(share);
  47. if (!treeID.HasValue)
  48. {
  49. header.Status = NTStatus.STATUS_INSUFF_SERVER_RESOURCES;
  50. return new ErrorResponse(request.CommandName);
  51. }
  52. header.TID = treeID.Value;
  53. if (isExtended)
  54. {
  55. return CreateTreeConnectResponseExtended(serviceName, supportFlags);
  56. }
  57. else
  58. {
  59. return CreateTreeConnectResponse(serviceName, supportFlags);
  60. }
  61. }
  62. private static TreeConnectAndXResponse CreateTreeConnectResponse(ServiceName serviceName, OptionalSupportFlags supportFlags)
  63. {
  64. TreeConnectAndXResponse response = new TreeConnectAndXResponse();
  65. response.OptionalSupport = supportFlags;
  66. response.NativeFileSystem = String.Empty;
  67. response.Service = serviceName;
  68. return response;
  69. }
  70. private static TreeConnectAndXResponseExtended CreateTreeConnectResponseExtended(ServiceName serviceName, OptionalSupportFlags supportFlags)
  71. {
  72. TreeConnectAndXResponseExtended response = new TreeConnectAndXResponseExtended();
  73. response.OptionalSupport = supportFlags;
  74. response.MaximalShareAccessRights.File = FileAccessMask.FILE_READ_DATA | FileAccessMask.FILE_WRITE_DATA | FileAccessMask.FILE_APPEND_DATA |
  75. FileAccessMask.FILE_READ_EA | FileAccessMask.FILE_WRITE_EA |
  76. FileAccessMask.FILE_EXECUTE |
  77. FileAccessMask.FILE_READ_ATTRIBUTES | FileAccessMask.FILE_WRITE_ATTRIBUTES |
  78. FileAccessMask.DELETE | FileAccessMask.READ_CONTROL | FileAccessMask.WRITE_DAC | FileAccessMask.WRITE_OWNER | FileAccessMask.SYNCHRONIZE;
  79. response.GuestMaximalShareAccessRights.File = FileAccessMask.FILE_READ_DATA | FileAccessMask.FILE_WRITE_DATA |
  80. FileAccessMask.FILE_READ_EA | FileAccessMask.FILE_WRITE_EA |
  81. FileAccessMask.FILE_READ_ATTRIBUTES | FileAccessMask.FILE_WRITE_ATTRIBUTES |
  82. FileAccessMask.READ_CONTROL | FileAccessMask.SYNCHRONIZE;
  83. response.NativeFileSystem = String.Empty;
  84. response.Service = serviceName;
  85. return response;
  86. }
  87. internal static SMB1Command GetTreeDisconnectResponse(SMB1Header header, TreeDisconnectRequest request, SMB1ConnectionState state)
  88. {
  89. SMB1Session session = state.GetSession(header.UID);
  90. if (!session.IsTreeConnected(header.TID))
  91. {
  92. header.Status = NTStatus.STATUS_SMB_BAD_TID;
  93. return new ErrorResponse(request.CommandName);
  94. }
  95. session.DisconnectTree(header.TID);
  96. return new TreeDisconnectResponse();
  97. }
  98. }
  99. }