internal static SMB1Command GetTreeConnectResponse(SMB1Header header, TreeConnectAndXRequest request, SMB1ConnectionState state, NamedPipeShare services, SMBShareCollection shares) { SMB1Session session = state.GetSession(header.UID); bool isExtended = (request.Flags & TreeConnectFlags.ExtendedResponse) > 0; string shareName = ServerPathUtils.GetShareName(request.Path); ISMBShare share; ServiceName serviceName; OptionalSupportFlags supportFlags; if (String.Equals(shareName, NamedPipeShare.NamedPipeShareName, StringComparison.InvariantCultureIgnoreCase)) { share = services; serviceName = ServiceName.NamedPipe; supportFlags = OptionalSupportFlags.SMB_SUPPORT_SEARCH_BITS | OptionalSupportFlags.SMB_CSC_NO_CACHING; } else { share = shares.GetShareFromName(shareName); serviceName = ServiceName.DiskShare; supportFlags = OptionalSupportFlags.SMB_SUPPORT_SEARCH_BITS | OptionalSupportFlags.SMB_CSC_CACHE_MANUAL_REINT; if (share == null) { header.Status = NTStatus.STATUS_OBJECT_PATH_NOT_FOUND; return(new ErrorResponse(request.CommandName)); } if (!((FileSystemShare)share).HasReadAccess(session.SecurityContext, @"\")) { state.LogToServer(Severity.Verbose, "Tree Connect to '{0}' failed. User '{1}' was denied access.", share.Name, session.UserName); header.Status = NTStatus.STATUS_ACCESS_DENIED; return(new ErrorResponse(request.CommandName)); } } ushort?treeID = session.AddConnectedTree(share); if (!treeID.HasValue) { header.Status = NTStatus.STATUS_INSUFF_SERVER_RESOURCES; return(new ErrorResponse(request.CommandName)); } state.LogToServer(Severity.Information, "Tree Connect: User '{0}' connected to '{1}'", session.UserName, share.Name); header.TID = treeID.Value; if (isExtended) { return(CreateTreeConnectResponseExtended(serviceName, supportFlags)); } else { return(CreateTreeConnectResponse(serviceName, supportFlags)); } }
internal static SMB2Command GetTreeConnectResponse(TreeConnectRequest request, SMB2ConnectionState state, NamedPipeShare services, SMBShareCollection shares) { SMB2Session session = state.GetSession(request.Header.SessionID); TreeConnectResponse response = new TreeConnectResponse(); string shareName = ServerPathUtils.GetShareName(request.Path); ISMBShare share; ShareType shareType; ShareFlags shareFlags; if (String.Equals(shareName, NamedPipeShare.NamedPipeShareName, StringComparison.OrdinalIgnoreCase)) { share = services; shareType = ShareType.Pipe; shareFlags = ShareFlags.NoCaching; } else { share = shares.GetShareFromName(shareName); if (share == null) { return(new ErrorResponse(request.CommandName, NTStatus.STATUS_OBJECT_PATH_NOT_FOUND)); } shareType = ShareType.Disk; shareFlags = GetShareCachingFlags(((FileSystemShare)share).CachingPolicy); if (!((FileSystemShare)share).HasReadAccess(session.SecurityContext, @"\")) { state.LogToServer(Severity.Verbose, "Tree Connect to '{0}' failed. User '{1}' was denied access.", share.Name, session.UserName); return(new ErrorResponse(request.CommandName, NTStatus.STATUS_ACCESS_DENIED)); } } uint?treeID = session.AddConnectedTree(share); if (!treeID.HasValue) { return(new ErrorResponse(request.CommandName, NTStatus.STATUS_INSUFF_SERVER_RESOURCES)); } state.LogToServer(Severity.Information, "Tree Connect: User '{0}' connected to '{1}' (SessionID: {2}, TreeID: {3})", session.UserName, share.Name, request.Header.SessionID, treeID.Value); response.Header.TreeID = treeID.Value; response.ShareType = shareType; response.ShareFlags = shareFlags; response.MaximalAccess = (AccessMask)(FileAccessMask.FILE_READ_DATA | FileAccessMask.FILE_WRITE_DATA | FileAccessMask.FILE_APPEND_DATA | FileAccessMask.FILE_READ_EA | FileAccessMask.FILE_WRITE_EA | FileAccessMask.FILE_EXECUTE | FileAccessMask.FILE_READ_ATTRIBUTES | FileAccessMask.FILE_WRITE_ATTRIBUTES) | AccessMask.DELETE | AccessMask.READ_CONTROL | AccessMask.WRITE_DAC | AccessMask.WRITE_OWNER | AccessMask.SYNCHRONIZE; return(response); }