123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126 |
- using System;
- using System.Collections.Generic;
- using SMBLibrary.Authentication;
- using SMBLibrary.SMB2;
- using Utilities;
- namespace SMBLibrary.Server.SMB2
- {
- internal class SetInfoHelper
- {
- internal static SMB2Command GetSetInfoResponse(SetInfoRequest request, ISMBShare share, SMB2ConnectionState state)
- {
- SMB2Session session = state.GetSession(request.Header.SessionID);
- OpenFileObject openFile = null;
- if (request.InfoType == InfoType.File || request.InfoType == InfoType.Security)
- {
- openFile = session.GetOpenFileObject(request.FileId);
- if (openFile == null)
- {
- state.LogToServer(Severity.Verbose, "SetFileInformation failed. Invalid FileId. (SessionID: {0}, TreeID: {1}, FileId: {2})", request.Header.SessionID, request.Header.TreeID, request.FileId.Volatile);
- return new ErrorResponse(request.CommandName, NTStatus.STATUS_FILE_CLOSED);
- }
- 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);
- return new ErrorResponse(request.CommandName, NTStatus.STATUS_ACCESS_DENIED);
- }
- }
- }
- if (request.InfoType == InfoType.File)
- {
- FileInformation information;
- try
- {
- information = FileInformation.GetFileInformation(request.Buffer, 0, request.FileInformationClass);
- }
- catch (UnsupportedInformationLevelException)
- {
- state.LogToServer(Severity.Verbose, "SetFileInformation on '{0}{1}' failed. Information class: {2}, NTStatus: STATUS_INVALID_INFO_CLASS.", share.Name, openFile.Path, request.FileInformationClass);
- return new ErrorResponse(request.CommandName, NTStatus.STATUS_INVALID_INFO_CLASS);
- }
- catch (NotImplementedException)
- {
- state.LogToServer(Severity.Verbose, "SetFileInformation on '{0}{1}' failed. Information class: {2}, NTStatus: STATUS_NOT_SUPPORTED.", share.Name, openFile.Path, request.FileInformationClass);
- return new ErrorResponse(request.CommandName, NTStatus.STATUS_NOT_SUPPORTED);
- }
- catch (Exception)
- {
- state.LogToServer(Severity.Verbose, "SetFileInformation on '{0}{1}' failed. Information class: {2}, NTStatus: STATUS_INVALID_PARAMETER.", share.Name, openFile.Path, request.FileInformationClass);
- return new ErrorResponse(request.CommandName, NTStatus.STATUS_INVALID_PARAMETER);
- }
- if ((share is FileSystemShare) && (information is FileRenameInformationType2))
- {
- string newFileName = ((FileRenameInformationType2)information).FileName;
- if (!newFileName.StartsWith(@"\"))
- {
- newFileName = @"\" + newFileName;
- }
- if (!((FileSystemShare)share).HasWriteAccess(session.SecurityContext, newFileName))
- {
- state.LogToServer(Severity.Verbose, "SetFileInformation: Rename '{0}{1}' to '{0}{2}' failed. User '{3}' was denied access.", share.Name, openFile.Path, newFileName, session.UserName);
- return new ErrorResponse(request.CommandName, NTStatus.STATUS_ACCESS_DENIED);
- }
- }
- NTStatus status = share.FileStore.SetFileInformation(openFile.Handle, information);
- if (status != NTStatus.STATUS_SUCCESS)
- {
- state.LogToServer(Severity.Verbose, "SetFileInformation on '{0}{1}' failed. Information class: {2}, NTStatus: {3}. (FileId: {4})", share.Name, openFile.Path, request.FileInformationClass, status, request.FileId.Volatile);
- return new ErrorResponse(request.CommandName, status);
- }
- if (information is FileRenameInformationType2)
- {
- string newFileName = ((FileRenameInformationType2)information).FileName;
- if (!newFileName.StartsWith(@"\"))
- {
- newFileName = @"\" + newFileName;
- }
- state.LogToServer(Severity.Verbose, "SetFileInformation: Rename '{0}{1}' to '{0}{2}' succeeded. (FileId: {3})", share.Name, openFile.Path, newFileName, request.FileId.Volatile);
- openFile.Path = newFileName;
- }
- else
- {
- state.LogToServer(Severity.Information, "SetFileInformation on '{0}{1}' succeeded. Information class: {2}. (FileId: {3})", share.Name, openFile.Path, request.FileInformationClass, request.FileId.Volatile);
- }
- return new SetInfoResponse();
- }
- else if (request.InfoType == InfoType.Security)
- {
- SecurityDescriptor securityDescriptor;
- try
- {
- securityDescriptor = new SecurityDescriptor(request.Buffer, 0);
- }
- catch
- {
- state.LogToServer(Severity.Verbose, "SetSecurityInformation on '{0}{1}' failed. NTStatus: STATUS_INVALID_PARAMETER.", share.Name, openFile.Path);
- return new ErrorResponse(request.CommandName, NTStatus.STATUS_INVALID_PARAMETER);
- }
- NTStatus status = share.FileStore.SetSecurityInformation(openFile, request.SecurityInformation, securityDescriptor);
- if (status != NTStatus.STATUS_SUCCESS)
- {
- state.LogToServer(Severity.Verbose, "SetSecurityInformation on '{0}{1}' failed. Security information: 0x{2}, NTStatus: {3}. (FileId: {4})", share.Name, openFile.Path, request.SecurityInformation.ToString("X"), status, request.FileId.Volatile);
- return new ErrorResponse(request.CommandName, status);
- }
- state.LogToServer(Severity.Information, "SetSecurityInformation on '{0}{1}' succeeded. Security information: 0x{2}. (FileId: {3})", share.Name, openFile.Path, request.SecurityInformation.ToString("X"), request.FileId.Volatile);
- return new SetInfoResponse();
- }
- return new ErrorResponse(request.CommandName, NTStatus.STATUS_NOT_SUPPORTED);
- }
- }
- }
|