def test_exception_needs_newer(self): with pytest.raises(SMBUnsupportedFeature) as exc: raise SMBUnsupportedFeature(Dialects.SMB_3_0_0, Dialects.SMB_3_1_1, "feature", True) assert str(exc.value) == "feature is not available on the " \ "negotiated dialect (768) SMB_3_0_0, " \ "requires dialect (785) SMB_3_1_1 or newer"
def read(self, offset, length, min_length=0, unbuffered=False, wait=True, send=True): """ Reads from an opened file or pipe Supports out of band send function, call this function with send=False to return a tuple of (SMB2ReadRequest, receive_func) instead of sending the the request and waiting for the response. The receive_func can be used to get the response from the server by passing in the Request that was used to sent it out of band. :param offset: The offset to start the read of the file. :param length: The number of bytes to read from the offset. :param min_length: The minimum number of bytes to be read for a successful operation. :param unbuffered: Whether to the server should cache the read data at intermediate layers, only value for SMB 3.0.2 or newer :param wait: If send=True, whether to wait for a response if STATUS_PENDING was received from the server or fail. :param send: Whether to send the request in the same call or return the message to the caller and the unpack function :return: A byte string of the bytes read """ if length > self.connection.max_read_size: raise SMBException("The requested read length %d is greater than " "the maximum negotiated read size %d" % (length, self.connection.max_read_size)) read = SMB2ReadRequest() read['length'] = length read['offset'] = offset read['minimum_count'] = min_length read['file_id'] = self.file_id read['padding'] = b"\x50" if unbuffered: if self.connection.dialect < Dialects.SMB_3_0_2: raise SMBUnsupportedFeature(self.connection.dialect, Dialects.SMB_3_0_2, "SMB2_READFLAG_READ_UNBUFFERED", True) read['flags'].set_flag(ReadFlags.SMB2_READFLAG_READ_UNBUFFERED) if not send: return read, self._read_response log.info("Session: %s, Tree Connect ID: %s - sending SMB2 Read " "Request for file %s" % (self.tree_connect.session.username, self.tree_connect.share_name, self.file_name)) log.debug(str(read)) request = self.connection.send(read, self.tree_connect.session.session_id, self.tree_connect.tree_connect_id) return self._read_response(request, wait)
def write(self, data, offset=0, write_through=False, unbuffered=False, wait=True, send=True): """ Writes data to an opened file. Supports out of band send function, call this function with send=False to return a tuple of (SMBWriteRequest, receive_func) instead of sending the the request and waiting for the response. The receive_func can be used to get the response from the server by passing in the Request that was used to sent it out of band. :param data: The bytes data to write. :param offset: The offset in the file to write the bytes at :param write_through: Whether written data is persisted to the underlying storage, not valid for SMB 2.0.2. :param unbuffered: Whether to the server should cache the write data at intermediate layers, only value for SMB 3.0.2 or newer :param wait: If send=True, whether to wait for a response if STATUS_PENDING was received from the server or fail. :param send: Whether to send the request in the same call or return the message to the caller and the unpack function :return: The number of bytes written """ data_len = len(data) if data_len > self.connection.max_write_size: raise SMBException("The requested write length %d is greater than " "the maximum negotiated write size %d" % (data_len, self.connection.max_write_size)) write = SMB2WriteRequest() write['length'] = len(data) write['offset'] = offset write['file_id'] = self.file_id write['buffer'] = data if write_through: if self.connection.dialect < Dialects.SMB_2_1_0: raise SMBUnsupportedFeature(self.connection.dialect, Dialects.SMB_2_1_0, "SMB2_WRITEFLAG_WRITE_THROUGH", True) write['flags'].set_flag(WriteFlags.SMB2_WRITEFLAG_WRITE_THROUGH) if unbuffered: if self.connection.dialect < Dialects.SMB_3_0_2: raise SMBUnsupportedFeature(self.connection.dialect, Dialects.SMB_3_0_2, "SMB2_WRITEFLAG_WRITE_UNBUFFERED", True) write['flags'].set_flag(WriteFlags.SMB2_WRITEFLAG_WRITE_UNBUFFERED) if not send: return write, self._write_response log.info("Session: %s, Tree Connect: %s - sending SMB2 Write Request " "for file %s" % (self.tree_connect.session.username, self.tree_connect.share_name, self.file_name)) log.debug(str(write)) request = self.connection.send(write, self.tree_connect.session.session_id, self.tree_connect.tree_connect_id) return self._write_response(request, wait)