public NTStatus SetFileInformation(object handle, SetInformation information) { int maxOutputLength = 4096; Transaction2SetFileInformationRequest subcommand = new Transaction2SetFileInformationRequest(); subcommand.FID = (ushort)handle; subcommand.SetInformation(information); Transaction2Request request = new Transaction2Request(); request.Setup = subcommand.GetSetup(); request.TransParameters = subcommand.GetParameters(m_client.Unicode); request.TransData = subcommand.GetData(m_client.Unicode); request.TotalDataCount = (ushort)request.TransData.Length; request.TotalParameterCount = (ushort)request.TransParameters.Length; request.MaxParameterCount = Transaction2SetFileInformationResponse.ParametersLength; request.MaxDataCount = (ushort)maxOutputLength; TrySendMessage(request); SMB1Message reply = m_client.WaitForMessage(CommandName.SMB_COM_TRANSACTION2); if (reply != null) { return(reply.Header.Status); } return(NTStatus.STATUS_INVALID_SMB); }
public void SetFileInformation(NtHandle handle, SetInformation information) { int maxOutputLength = 4096; Transaction2SetFileInformationRequest subcommand = new Transaction2SetFileInformationRequest { FID = ((Smb1Handle)handle).FID, }; subcommand.SetInformation(information); Transaction2Request request = new Transaction2Request { Setup = subcommand.GetSetup(), TransParameters = subcommand.GetParameters(m_client.Unicode), TransData = subcommand.GetData(m_client.Unicode) }; request.TotalDataCount = (ushort)request.TransData.Length; request.TotalParameterCount = (ushort)request.TransParameters.Length; request.MaxParameterCount = Transaction2SetFileInformationResponse.ParametersLength; request.MaxDataCount = (ushort)maxOutputLength; TrySendMessage(request); SMB1Message reply = m_client.WaitForMessage(CommandName.SMB_COM_TRANSACTION2); reply.IsSuccessElseThrow(); }
public void SetFileInformation(NtHandle handle, FileInformation information) { if (!m_client.InfoLevelPassthrough) { throw new NotSupportedException("Server does not support InfoLevelPassthrough"); } if (information is FileRenameInformationType2 fileRenameInformationType2) { FileRenameInformationType1 informationType1 = new FileRenameInformationType1 { FileName = fileRenameInformationType2.FileName, ReplaceIfExists = fileRenameInformationType2.ReplaceIfExists, RootDirectory = (uint)fileRenameInformationType2.RootDirectory }; information = informationType1; } int maxOutputLength = 4096; Transaction2SetFileInformationRequest subcommand = new Transaction2SetFileInformationRequest { FID = ((Smb1Handle)handle).FID, }; subcommand.SetInformation(information); Transaction2Request request = new Transaction2Request { Setup = subcommand.GetSetup(), TransParameters = subcommand.GetParameters(m_client.Unicode), TransData = subcommand.GetData(m_client.Unicode) }; request.TotalDataCount = (ushort)request.TransData.Length; request.TotalParameterCount = (ushort)request.TransParameters.Length; request.MaxParameterCount = Transaction2SetFileInformationResponse.ParametersLength; request.MaxDataCount = (ushort)maxOutputLength; TrySendMessage(request); SMB1Message reply = m_client.WaitForMessage(CommandName.SMB_COM_TRANSACTION2); reply.IsSuccessElseThrow(); }
public NTStatus SetFileInformation(object handle, FileInformation information) { if (m_client.InfoLevelPassthrough) { if (information is FileRenameInformationType2) { FileRenameInformationType1 informationType1 = new FileRenameInformationType1(); informationType1.FileName = ((FileRenameInformationType2)information).FileName; informationType1.ReplaceIfExists = ((FileRenameInformationType2)information).ReplaceIfExists; informationType1.RootDirectory = (uint)((FileRenameInformationType2)information).RootDirectory; information = informationType1; } int maxOutputLength = 4096; Transaction2SetFileInformationRequest subcommand = new Transaction2SetFileInformationRequest(); subcommand.FID = (ushort)handle; subcommand.SetInformation(information); Transaction2Request request = new Transaction2Request(); request.Setup = subcommand.GetSetup(); request.TransParameters = subcommand.GetParameters(m_client.Unicode); request.TransData = subcommand.GetData(m_client.Unicode); request.TotalDataCount = (ushort)request.TransData.Length; request.TotalParameterCount = (ushort)request.TransParameters.Length; request.MaxParameterCount = Transaction2SetFileInformationResponse.ParametersLength; request.MaxDataCount = (ushort)maxOutputLength; TrySendMessage(request); SMB1Message reply = m_client.WaitForMessage(CommandName.SMB_COM_TRANSACTION2); if (reply != null) { return(reply.Header.Status); } return(NTStatus.STATUS_INVALID_SMB); } else { throw new NotSupportedException("Server does not support InfoLevelPassthrough"); } }
internal static Transaction2SetFileInformationResponse GetSubcommandResponse(SMBHeader header, Transaction2SetFileInformationRequest subcommand, FileSystemShare share, StateObject state) { string openedFilePath = state.GetOpenedFilePath(subcommand.FID); if (openedFilePath == null) { header.Status = NTStatus.STATUS_INVALID_HANDLE; return(null); } Transaction2SetFileInformationResponse response = new Transaction2SetFileInformationResponse(); switch (subcommand.InformationLevel) { case SetInformationLevel.SMB_INFO_STANDARD: { return(response); } case SetInformationLevel.SMB_INFO_SET_EAS: { throw new NotImplementedException(); } case SetInformationLevel.SMB_SET_FILE_BASIC_INFO: { string userName = state.GetConnectedUserName(header.UID); if (!share.HasWriteAccess(userName)) { header.Status = NTStatus.STATUS_ACCESS_DENIED; return(null); } SetFileBasicInfo info = (SetFileBasicInfo)subcommand.SetInfo; bool isHidden = (info.ExtFileAttributes & ExtendedFileAttributes.Hidden) > 0; bool isReadonly = (info.ExtFileAttributes & ExtendedFileAttributes.Readonly) > 0; bool isArchived = (info.ExtFileAttributes & ExtendedFileAttributes.Archive) > 0; try { share.FileSystem.SetAttributes(openedFilePath, isHidden, isReadonly, isArchived); } catch (UnauthorizedAccessException) { header.Status = NTStatus.STATUS_ACCESS_DENIED; return(null); } DateTime?creationTime = null; DateTime?lastWriteDT = null; DateTime?lastAccessTime = null; if (info.CreationTime != SMBHelper.FileTimeNotSpecified) { creationTime = info.CreationTime; } if (info.LastWriteTime != SMBHelper.FileTimeNotSpecified) { lastWriteDT = info.LastWriteTime; } if (info.LastAccessTime != SMBHelper.FileTimeNotSpecified) { lastAccessTime = info.LastAccessTime; } try { share.FileSystem.SetDates(openedFilePath, creationTime, lastWriteDT, lastAccessTime); } catch (IOException ex) { ushort errorCode = IOExceptionHelper.GetWin32ErrorCode(ex); if (errorCode == (ushort)Win32Error.ERROR_SHARING_VIOLATION) { // Returning STATUS_SHARING_VIOLATION is undocumented but apparently valid header.Status = NTStatus.STATUS_SHARING_VIOLATION; return(null); } else { header.Status = NTStatus.STATUS_DATA_ERROR; return(null); } } catch (UnauthorizedAccessException) { header.Status = NTStatus.STATUS_ACCESS_DENIED; return(null); } return(response); } case SetInformationLevel.SMB_SET_FILE_DISPOSITION_INFO: { if (((SetFileDispositionInfo)subcommand.SetInfo).DeletePending) { // We're supposed to delete the file on close, but it's too late to report errors at this late stage string userName = state.GetConnectedUserName(header.UID); if (!share.HasWriteAccess(userName)) { header.Status = NTStatus.STATUS_ACCESS_DENIED; return(null); } try { share.FileSystem.Delete(openedFilePath); } catch (IOException) { header.Status = NTStatus.STATUS_FILE_LOCK_CONFLICT; return(null); } catch (UnauthorizedAccessException) { header.Status = NTStatus.STATUS_ACCESS_DENIED; return(null); } } return(response); } case SetInformationLevel.SMB_SET_FILE_ALLOCATION_INFO: { // This subcommand is used to set the file length in bytes. // Note: the input will NOT be a multiple of the cluster size / bytes per sector. ulong allocationSize = ((SetFileAllocationInfo)subcommand.SetInfo).AllocationSize; try { Stream stream = share.FileSystem.OpenFile(openedFilePath, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite); stream.SetLength((long)allocationSize); stream.Close(); } catch { } return(response); } case SetInformationLevel.SMB_SET_FILE_END_OF_FILE_INFO: { ulong endOfFile = ((SetFileEndOfFileInfo)subcommand.SetInfo).EndOfFile; try { Stream stream = share.FileSystem.OpenFile(openedFilePath, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite); stream.SetLength((long)endOfFile); stream.Close(); } catch { } return(response); } default: { throw new InvalidRequestException(); } } }
internal static Transaction2SetFileInformationResponse GetSubcommandResponse(SMB1Header header, Transaction2SetFileInformationRequest subcommand, ISMBShare share, SMB1ConnectionState state) { SMB1Session session = state.GetSession(header.UID); OpenFileObject openFile = session.GetOpenFileObject(subcommand.FID); if (openFile == null) { state.LogToServer(Severity.Verbose, "SetFileInformation failed. Invalid FID. (UID: {0}, TID: {1}, FID: {2})", header.UID, header.TID, subcommand.FID); header.Status = NTStatus.STATUS_INVALID_HANDLE; return(null); } if (share is FileSystemShare) { if (!((FileSystemShare)share).HasWriteAccess(session.SecurityContext, openFile.Path)) { state.LogToServer(Severity.Verbose, "SetFileInformation on '{0}{1}' failed. User '{2}' was denied access.", share.Name, openFile.Path, session.UserName); header.Status = NTStatus.STATUS_ACCESS_DENIED; return(null); } } if (subcommand.IsPassthroughInformationLevel) { FileInformation fileInfo; try { fileInfo = FileInformation.GetFileInformation(subcommand.InformationBytes, 0, subcommand.FileInformationClass); } catch (UnsupportedInformationLevelException) { state.LogToServer(Severity.Verbose, "SetFileInformation on '{0}{1}' failed. Information class: {2}, NTStatus: STATUS_OS2_INVALID_LEVEL.", share.Name, openFile.Path, subcommand.FileInformationClass); header.Status = NTStatus.STATUS_OS2_INVALID_LEVEL; return(null); } catch (Exception) { state.LogToServer(Severity.Verbose, "SetFileInformation on '{0}{1}' failed. Information class: {2}, NTStatus: STATUS_INVALID_PARAMETER.", share.Name, openFile.Path, subcommand.FileInformationClass); header.Status = NTStatus.STATUS_INVALID_PARAMETER; return(null); } NTStatus status = share.FileStore.SetFileInformation(openFile.Handle, fileInfo); if (status != NTStatus.STATUS_SUCCESS) { state.LogToServer(Severity.Verbose, "SetFileInformation on '{0}{1}' failed. Information class: {2}, NTStatus: {3}. (FID: {4})", share.Name, openFile.Path, subcommand.FileInformationClass, status, subcommand.FID); header.Status = status; return(null); } state.LogToServer(Severity.Information, "SetFileInformation on '{0}{1}' succeeded. Information class: {2}. (FID: {3})", share.Name, openFile.Path, subcommand.FileInformationClass, subcommand.FID); } else { SetInformation information; try { information = SetInformation.GetSetInformation(subcommand.InformationBytes, subcommand.SetInformationLevel); } catch (UnsupportedInformationLevelException) { state.LogToServer(Severity.Verbose, "SetFileInformation on '{0}{1}' failed. Information level: {2}, NTStatus: STATUS_OS2_INVALID_LEVEL.", share.Name, openFile.Path, subcommand.SetInformationLevel); header.Status = NTStatus.STATUS_OS2_INVALID_LEVEL; return(null); } catch (Exception) { state.LogToServer(Severity.Verbose, "SetFileInformation on '{0}{1}' failed. Information level: {2}, NTStatus: STATUS_INVALID_PARAMETER.", share.Name, openFile.Path, subcommand.SetInformationLevel); header.Status = NTStatus.STATUS_INVALID_PARAMETER; return(null); } NTStatus status = SMB1FileStoreHelper.SetFileInformation(share.FileStore, openFile.Handle, information); if (status != NTStatus.STATUS_SUCCESS) { state.LogToServer(Severity.Verbose, "SetFileInformation on '{0}{1}' failed. Information level: {2}, NTStatus: {3}. (FID: {4})", share.Name, openFile.Path, subcommand.SetInformationLevel, status, subcommand.FID); header.Status = status; return(null); } state.LogToServer(Severity.Information, "SetFileInformation on '{0}{1}' succeeded. Information level: {2}. (FID: {3})", share.Name, openFile.Path, subcommand.SetInformationLevel, subcommand.FID); } Transaction2SetFileInformationResponse response = new Transaction2SetFileInformationResponse(); return(response); }