/* Maximum buffer size value we can send with 1 credit */
#define SMB2_MAX_BUFFER_SIZE 65536
+static inline struct smb2_sync_hdr *get_sync_hdr(void *buf)
+{
+ return &(((struct smb2_hdr *)buf)->sync_hdr);
+}
+
#endif /* _SMB2_GLOB_H */
#include "smb2pdu.h"
#include "smb2proto.h"
#include "smb2status.h"
+#include "smb2glob.h"
struct status_to_posix_error {
__le32 smb2_status;
int
map_smb2_to_linux_error(char *buf, bool log_err)
{
- struct smb2_hdr *hdr = (struct smb2_hdr *)buf;
+ struct smb2_sync_hdr *shdr = get_sync_hdr(buf);
unsigned int i;
int rc = -EIO;
- __le32 smb2err = hdr->Status;
+ __le32 smb2err = shdr->Status;
if (smb2err == 0)
return 0;
#include "cifs_debug.h"
#include "cifs_unicode.h"
#include "smb2status.h"
+#include "smb2glob.h"
static int
-check_smb2_hdr(struct smb2_hdr *hdr, __u64 mid)
+check_smb2_hdr(struct smb2_sync_hdr *shdr, __u64 mid)
{
- __u64 wire_mid = le64_to_cpu(hdr->MessageId);
+ __u64 wire_mid = le64_to_cpu(shdr->MessageId);
/*
* Make sure that this really is an SMB, that it is a response,
* and that the message ids match.
*/
- if ((hdr->ProtocolId == SMB2_PROTO_NUMBER) &&
+ if ((shdr->ProtocolId == SMB2_PROTO_NUMBER) &&
(mid == wire_mid)) {
- if (hdr->Flags & SMB2_FLAGS_SERVER_TO_REDIR)
+ if (shdr->Flags & SMB2_FLAGS_SERVER_TO_REDIR)
return 0;
else {
/* only one valid case where server sends us request */
- if (hdr->Command == SMB2_OPLOCK_BREAK)
+ if (shdr->Command == SMB2_OPLOCK_BREAK)
return 0;
else
cifs_dbg(VFS, "Received Request not response\n");
}
} else { /* bad signature or mid */
- if (hdr->ProtocolId != SMB2_PROTO_NUMBER)
+ if (shdr->ProtocolId != SMB2_PROTO_NUMBER)
cifs_dbg(VFS, "Bad protocol string signature header %x\n",
- le32_to_cpu(hdr->ProtocolId));
+ le32_to_cpu(shdr->ProtocolId));
if (mid != wire_mid)
cifs_dbg(VFS, "Mids do not match: %llu and %llu\n",
mid, wire_mid);
int
smb2_check_message(char *buf, unsigned int length, struct TCP_Server_Info *srvr)
{
- struct smb2_hdr *hdr = (struct smb2_hdr *)buf;
- struct smb2_pdu *pdu = (struct smb2_pdu *)hdr;
+ struct smb2_pdu *pdu = (struct smb2_pdu *)buf;
+ struct smb2_hdr *hdr = &pdu->hdr;
+ struct smb2_sync_hdr *shdr = get_sync_hdr(buf);
__u64 mid;
__u32 len = get_rfc1002_length(buf);
__u32 clc_len; /* calculated length */
* ie Validate the wct via smb2_struct_sizes table above
*/
- if (hdr->ProtocolId == SMB2_TRANSFORM_PROTO_NUM) {
+ if (shdr->ProtocolId == SMB2_TRANSFORM_PROTO_NUM) {
struct smb2_transform_hdr *thdr =
(struct smb2_transform_hdr *)buf;
struct cifs_ses *ses = NULL;
}
}
-
- mid = le64_to_cpu(hdr->MessageId);
+ mid = le64_to_cpu(shdr->MessageId);
if (length < sizeof(struct smb2_pdu)) {
- if ((length >= sizeof(struct smb2_hdr)) && (hdr->Status != 0)) {
+ if ((length >= sizeof(struct smb2_hdr))
+ && (shdr->Status != 0)) {
pdu->StructureSize2 = 0;
/*
* As with SMB/CIFS, on some error cases servers may
return 1;
}
- if (check_smb2_hdr(hdr, mid))
+ if (check_smb2_hdr(shdr, mid))
return 1;
- if (hdr->StructureSize != SMB2_HEADER_STRUCTURE_SIZE) {
+ if (shdr->StructureSize != SMB2_HEADER_STRUCTURE_SIZE) {
cifs_dbg(VFS, "Illegal structure size %u\n",
- le16_to_cpu(hdr->StructureSize));
+ le16_to_cpu(shdr->StructureSize));
return 1;
}
- command = le16_to_cpu(hdr->Command);
+ command = le16_to_cpu(shdr->Command);
if (command >= NUMBER_OF_SMB2_COMMANDS) {
cifs_dbg(VFS, "Illegal SMB2 command %d\n", command);
return 1;
}
if (smb2_rsp_struct_sizes[command] != pdu->StructureSize2) {
- if (command != SMB2_OPLOCK_BREAK_HE && (hdr->Status == 0 ||
+ if (command != SMB2_OPLOCK_BREAK_HE && (shdr->Status == 0 ||
pdu->StructureSize2 != SMB2_ERROR_STRUCTURE_SIZE2)) {
/* error packets have 9 byte structure size */
cifs_dbg(VFS, "Illegal response size %u for command %d\n",
le16_to_cpu(pdu->StructureSize2), command);
return 1;
- } else if (command == SMB2_OPLOCK_BREAK_HE && (hdr->Status == 0)
+ } else if (command == SMB2_OPLOCK_BREAK_HE
+ && (shdr->Status == 0)
&& (le16_to_cpu(pdu->StructureSize2) != 44)
&& (le16_to_cpu(pdu->StructureSize2) != 36)) {
/* special case for SMB2.1 lease break message */
clc_len, 4 + len, mid);
/* create failed on symlink */
if (command == SMB2_CREATE_HE &&
- hdr->Status == STATUS_STOPPED_ON_SYMLINK)
+ shdr->Status == STATUS_STOPPED_ON_SYMLINK)
return 0;
/* Windows 7 server returns 24 bytes more */
if (clc_len + 20 == len && command == SMB2_OPLOCK_BREAK_HE)
char *
smb2_get_data_area_len(int *off, int *len, struct smb2_hdr *hdr)
{
+ struct smb2_sync_hdr *shdr = get_sync_hdr(hdr);
*off = 0;
*len = 0;
/* error responses do not have data area */
- if (hdr->Status && hdr->Status != STATUS_MORE_PROCESSING_REQUIRED &&
+ if (shdr->Status && shdr->Status != STATUS_MORE_PROCESSING_REQUIRED &&
(((struct smb2_err_rsp *)hdr)->StructureSize) ==
SMB2_ERROR_STRUCTURE_SIZE2)
return NULL;
* of the data buffer offset and data buffer length for the particular
* command.
*/
- switch (hdr->Command) {
+ switch (shdr->Command) {
case SMB2_NEGOTIATE:
*off = le16_to_cpu(
((struct smb2_negotiate_rsp *)hdr)->SecurityBufferOffset);
/* return pointer to beginning of data area, ie offset from SMB start */
if ((*off != 0) && (*len != 0))
- return (char *)(&hdr->ProtocolId) + *off;
+ return (char *)shdr + *off;
else
return NULL;
}
unsigned int
smb2_calc_size(void *buf)
{
- struct smb2_hdr *hdr = (struct smb2_hdr *)buf;
- struct smb2_pdu *pdu = (struct smb2_pdu *)hdr;
+ struct smb2_pdu *pdu = (struct smb2_pdu *)buf;
+ struct smb2_hdr *hdr = &pdu->hdr;
+ struct smb2_sync_hdr *shdr = get_sync_hdr(hdr);
int offset; /* the offset from the beginning of SMB to data area */
int data_length; /* the length of the variable length data area */
/* Structure Size has already been checked to make sure it is 64 */
- int len = 4 + le16_to_cpu(pdu->hdr.StructureSize);
+ int len = 4 + le16_to_cpu(shdr->StructureSize);
/*
* StructureSize2, ie length of fixed parameter area has already
*/
len += le16_to_cpu(pdu->StructureSize2);
- if (has_smb2_data_area[le16_to_cpu(hdr->Command)] == false)
+ if (has_smb2_data_area[le16_to_cpu(shdr->Command)] == false)
goto calc_size_exit;
smb2_get_data_area_len(&offset, &data_length, hdr);
cifs_dbg(FYI, "Checking for oplock break\n");
- if (rsp->hdr.Command != SMB2_OPLOCK_BREAK)
+ if (rsp->hdr.sync_hdr.Command != SMB2_OPLOCK_BREAK)
return false;
if (rsp->StructureSize !=
static unsigned int
smb2_get_credits(struct mid_q_entry *mid)
{
- return le16_to_cpu(((struct smb2_hdr *)mid->resp_buf)->CreditRequest);
+ struct smb2_sync_hdr *shdr = get_sync_hdr(mid->resp_buf);
+
+ return le16_to_cpu(shdr->CreditRequest);
}
static int
smb2_find_mid(struct TCP_Server_Info *server, char *buf)
{
struct mid_q_entry *mid;
- struct smb2_hdr *hdr = (struct smb2_hdr *)buf;
- __u64 wire_mid = le64_to_cpu(hdr->MessageId);
+ struct smb2_sync_hdr *shdr = get_sync_hdr(buf);
+ __u64 wire_mid = le64_to_cpu(shdr->MessageId);
- if (hdr->ProtocolId == SMB2_TRANSFORM_PROTO_NUM) {
+ if (shdr->ProtocolId == SMB2_TRANSFORM_PROTO_NUM) {
cifs_dbg(VFS, "encrypted frame parsing not supported yet");
return NULL;
}
list_for_each_entry(mid, &server->pending_mid_q, qhead) {
if ((mid->mid == wire_mid) &&
(mid->mid_state == MID_REQUEST_SUBMITTED) &&
- (mid->command == hdr->Command)) {
+ (mid->command == shdr->Command)) {
spin_unlock(&GlobalMid_Lock);
return mid;
}
smb2_dump_detail(void *buf)
{
#ifdef CONFIG_CIFS_DEBUG2
- struct smb2_hdr *smb = (struct smb2_hdr *)buf;
+ struct smb2_sync_hdr *shdr = get_sync_hdr(buf);
cifs_dbg(VFS, "Cmd: %d Err: 0x%x Flags: 0x%x Mid: %llu Pid: %d\n",
- smb->Command, smb->Status, smb->Flags, smb->MessageId,
- smb->ProcessId);
- cifs_dbg(VFS, "smb buf %p len %u\n", smb, smb2_calc_size(smb));
+ shdr->Command, shdr->Status, shdr->Flags, shdr->MessageId,
+ shdr->ProcessId);
+ cifs_dbg(VFS, "smb buf %p len %u\n", buf, smb2_calc_size(buf));
#endif
}
static bool
smb2_is_status_pending(char *buf, struct TCP_Server_Info *server, int length)
{
- struct smb2_hdr *hdr = (struct smb2_hdr *)buf;
+ struct smb2_sync_hdr *shdr = get_sync_hdr(buf);
- if (hdr->Status != STATUS_PENDING)
+ if (shdr->Status != STATUS_PENDING)
return false;
if (!length) {
spin_lock(&server->req_lock);
- server->credits += le16_to_cpu(hdr->CreditRequest);
+ server->credits += le16_to_cpu(shdr->CreditRequest);
spin_unlock(&server->req_lock);
wake_up(&server->request_q);
}
const struct cifs_tcon *tcon)
{
struct smb2_pdu *pdu = (struct smb2_pdu *)hdr;
+ struct smb2_sync_hdr *shdr = get_sync_hdr(hdr);
char *temp = (char *)hdr;
/* lookup word count ie StructureSize from table */
__u16 parmsize = smb2_req_struct_sizes[le16_to_cpu(smb2_cmd)];
memset(temp, 0, 256);
/* Note this is only network field converted to big endian */
- hdr->smb2_buf_length = cpu_to_be32(parmsize + sizeof(struct smb2_hdr)
- - 4 /* RFC 1001 length field itself not counted */);
+ hdr->smb2_buf_length =
+ cpu_to_be32(parmsize + sizeof(struct smb2_sync_hdr));
- hdr->ProtocolId = SMB2_PROTO_NUMBER;
- hdr->StructureSize = cpu_to_le16(64);
- hdr->Command = smb2_cmd;
+ shdr->ProtocolId = SMB2_PROTO_NUMBER;
+ shdr->StructureSize = cpu_to_le16(64);
+ shdr->Command = smb2_cmd;
if (tcon && tcon->ses && tcon->ses->server) {
struct TCP_Server_Info *server = tcon->ses->server;
spin_lock(&server->req_lock);
/* Request up to 2 credits but don't go over the limit. */
if (server->credits >= server->max_credits)
- hdr->CreditRequest = cpu_to_le16(0);
+ shdr->CreditRequest = cpu_to_le16(0);
else
- hdr->CreditRequest = cpu_to_le16(
+ shdr->CreditRequest = cpu_to_le16(
min_t(int, server->max_credits -
server->credits, 2));
spin_unlock(&server->req_lock);
} else {
- hdr->CreditRequest = cpu_to_le16(2);
+ shdr->CreditRequest = cpu_to_le16(2);
}
- hdr->ProcessId = cpu_to_le32((__u16)current->tgid);
+ shdr->ProcessId = cpu_to_le32((__u16)current->tgid);
if (!tcon)
goto out;
/* See sections 2.2.4 and 3.2.4.1.5 of MS-SMB2 */
if ((tcon->ses) && (tcon->ses->server) &&
(tcon->ses->server->capabilities & SMB2_GLOBAL_CAP_LARGE_MTU))
- hdr->CreditCharge = cpu_to_le16(1);
+ shdr->CreditCharge = cpu_to_le16(1);
/* else CreditCharge MBZ */
- hdr->TreeId = tcon->tid;
+ shdr->TreeId = tcon->tid;
/* Uid is not converted */
if (tcon->ses)
- hdr->SessionId = tcon->ses->Suid;
+ shdr->SessionId = tcon->ses->Suid;
/*
* If we would set SMB2_FLAGS_DFS_OPERATIONS on open we also would have
* but it is safer to net set it for now.
*/
/* if (tcon->share_flags & SHI1005_FLAGS_DFS)
- hdr->Flags |= SMB2_FLAGS_DFS_OPERATIONS; */
+ shdr->Flags |= SMB2_FLAGS_DFS_OPERATIONS; */
if (tcon->ses && tcon->ses->server && tcon->ses->server->sign)
- hdr->Flags |= SMB2_FLAGS_SIGNED;
+ shdr->Flags |= SMB2_FLAGS_SIGNED;
out:
pdu->StructureSize2 = cpu_to_le16(parmsize);
return;
if (rc)
return rc;
- req->hdr.SessionId = 0;
+ req->hdr.sync_hdr.SessionId = 0;
req->Dialects[0] = cpu_to_le16(ses->server->vals->protocol_id);
if (rc)
return rc;
- req->hdr.SessionId = 0; /* First session, not a reauthenticate */
+ /* First session, not a reauthenticate */
+ req->hdr.sync_hdr.SessionId = 0;
/* if reconnect, we need to send previous sess id, otherwise it is 0 */
req->PreviousSessionId = sess_data->previous_session;
req->Flags = 0; /* MBZ */
/* to enable echos and oplocks */
- req->hdr.CreditRequest = cpu_to_le16(3);
+ req->hdr.sync_hdr.CreditRequest = cpu_to_le16(3);
/* only one of SMB2 signing flags may be set in SMB2 request */
if (server->sign)
goto out_put_spnego_key;
rsp = (struct smb2_sess_setup_rsp *)sess_data->iov[0].iov_base;
- ses->Suid = rsp->hdr.SessionId;
+ ses->Suid = rsp->hdr.sync_hdr.SessionId;
ses->session_flags = le16_to_cpu(rsp->SessionFlags);
if (ses->session_flags & SMB2_SESSION_FLAG_ENCRYPT_DATA)
/* If true, rc here is expected and not an error */
if (sess_data->buf0_type != CIFS_NO_BUFFER &&
- rsp->hdr.Status == STATUS_MORE_PROCESSING_REQUIRED)
+ rsp->hdr.sync_hdr.Status == STATUS_MORE_PROCESSING_REQUIRED)
rc = 0;
if (rc)
cifs_dbg(FYI, "rawntlmssp session setup challenge phase\n");
- ses->Suid = rsp->hdr.SessionId;
+ ses->Suid = rsp->hdr.sync_hdr.SessionId;
ses->session_flags = le16_to_cpu(rsp->SessionFlags);
if (ses->session_flags & SMB2_SESSION_FLAG_ENCRYPT_DATA)
cifs_dbg(VFS, "SMB3 encryption not supported yet\n");
goto out;
req = (struct smb2_sess_setup_req *) sess_data->iov[0].iov_base;
- req->hdr.SessionId = ses->Suid;
+ req->hdr.sync_hdr.SessionId = ses->Suid;
rc = build_ntlmssp_auth_blob(&ntlmssp_blob, &blob_length, ses,
sess_data->nls_cp);
rsp = (struct smb2_sess_setup_rsp *)sess_data->iov[0].iov_base;
- ses->Suid = rsp->hdr.SessionId;
+ ses->Suid = rsp->hdr.sync_hdr.SessionId;
ses->session_flags = le16_to_cpu(rsp->SessionFlags);
if (ses->session_flags & SMB2_SESSION_FLAG_ENCRYPT_DATA)
cifs_dbg(VFS, "SMB3 encryption not supported yet\n");
return rc;
/* since no tcon, smb2_init can not do this, so do here */
- req->hdr.SessionId = ses->Suid;
+ req->hdr.sync_hdr.SessionId = ses->Suid;
if (server->sign)
- req->hdr.Flags |= SMB2_FLAGS_SIGNED;
+ req->hdr.sync_hdr.Flags |= SMB2_FLAGS_SIGNED;
rc = SendReceiveNoRsp(xid, ses, (char *) &req->hdr, 0);
/*
if (tcon == NULL) {
/* since no tcon, smb2_init can not do this, so do here */
- req->hdr.SessionId = ses->Suid;
+ req->hdr.sync_hdr.SessionId = ses->Suid;
/* if (ses->server->sec_mode & SECMODE_SIGN_REQUIRED)
req->hdr.Flags |= SMB2_FLAGS_SIGNED; */
}
}
if (tcon == NULL) {
- ses->ipc_tid = rsp->hdr.TreeId;
+ ses->ipc_tid = rsp->hdr.sync_hdr.TreeId;
goto tcon_exit;
}
tcon->maximal_access = le32_to_cpu(rsp->MaximalAccess);
tcon->tidStatus = CifsGood;
tcon->need_reconnect = false;
- tcon->tid = rsp->hdr.TreeId;
+ tcon->tid = rsp->hdr.sync_hdr.TreeId;
strlcpy(tcon->treeName, tree, sizeof(tcon->treeName));
if ((rsp->Capabilities & SMB2_SHARE_CAP_DFS) &&
return rc;
tcon_error_exit:
- if (rsp->hdr.Status == STATUS_BAD_NETWORK_NAME) {
+ if (rsp->hdr.sync_hdr.Status == STATUS_BAD_NETWORK_NAME) {
cifs_dbg(VFS, "BAD_NETWORK_NAME: %s\n", tree);
if (tcon)
tcon->bad_network_name = true;
{
struct smb2_ioctl_req *req;
struct smb2_ioctl_rsp *rsp;
+ struct smb2_sync_hdr *shdr;
struct TCP_Server_Info *server;
struct cifs_ses *ses;
struct kvec iov[2];
goto ioctl_exit;
}
- memcpy(*out_data,
- (char *)&rsp->hdr.ProtocolId + le32_to_cpu(rsp->OutputOffset),
- *plen);
+ shdr = get_sync_hdr(rsp);
+ memcpy(*out_data, (char *)shdr + le32_to_cpu(rsp->OutputOffset), *plen);
ioctl_exit:
free_rsp_buf(resp_buftype, rsp);
return rc;
smb2_echo_callback(struct mid_q_entry *mid)
{
struct TCP_Server_Info *server = mid->callback_data;
- struct smb2_echo_rsp *smb2 = (struct smb2_echo_rsp *)mid->resp_buf;
+ struct smb2_echo_rsp *rsp = (struct smb2_echo_rsp *)mid->resp_buf;
unsigned int credits_received = 1;
if (mid->mid_state == MID_RESPONSE_RECEIVED)
- credits_received = le16_to_cpu(smb2->hdr.CreditRequest);
+ credits_received = le16_to_cpu(rsp->hdr.sync_hdr.CreditRequest);
mutex_lock(&server->srv_mutex);
DeleteMidQEntry(mid);
if (rc)
return rc;
- req->hdr.CreditRequest = cpu_to_le16(1);
+ req->hdr.sync_hdr.CreditRequest = cpu_to_le16(1);
iov.iov_base = (char *)req;
/* 4 for rfc1002 length field */
{
int rc = -EACCES;
struct smb2_read_req *req = NULL;
+ struct smb2_sync_hdr *shdr;
rc = small_smb2_init(SMB2_READ, io_parms->tcon, (void **) &req);
if (rc)
if (io_parms->tcon->ses->server == NULL)
return -ECONNABORTED;
- req->hdr.ProcessId = cpu_to_le32(io_parms->pid);
+ shdr = get_sync_hdr(req);
+ shdr->ProcessId = cpu_to_le32(io_parms->pid);
req->PersistentFileId = io_parms->persistent_fid;
req->VolatileFileId = io_parms->volatile_fid;
if (request_type & CHAINED_REQUEST) {
if (!(request_type & END_OF_CHAIN)) {
/* 4 for rfc1002 length field */
- req->hdr.NextCommand =
+ shdr->NextCommand =
cpu_to_le32(get_rfc1002_length(req) + 4);
} else /* END_OF_CHAIN */
- req->hdr.NextCommand = 0;
+ shdr->NextCommand = 0;
if (request_type & RELATED_REQUEST) {
- req->hdr.Flags |= SMB2_FLAGS_RELATED_OPERATIONS;
+ shdr->Flags |= SMB2_FLAGS_RELATED_OPERATIONS;
/*
* Related requests use info from previous read request
* in chain.
*/
- req->hdr.SessionId = 0xFFFFFFFF;
- req->hdr.TreeId = 0xFFFFFFFF;
+ shdr->SessionId = 0xFFFFFFFF;
+ shdr->TreeId = 0xFFFFFFFF;
req->PersistentFileId = 0xFFFFFFFF;
req->VolatileFileId = 0xFFFFFFFF;
}
struct cifs_readdata *rdata = mid->callback_data;
struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
struct TCP_Server_Info *server = tcon->ses->server;
- struct smb2_hdr *buf = (struct smb2_hdr *)rdata->iov.iov_base;
+ struct smb2_sync_hdr *shdr = get_sync_hdr(rdata->iov.iov_base);
unsigned int credits_received = 1;
struct smb_rqst rqst = { .rq_iov = &rdata->iov,
.rq_nvec = 1,
switch (mid->mid_state) {
case MID_RESPONSE_RECEIVED:
- credits_received = le16_to_cpu(buf->CreditRequest);
+ credits_received = le16_to_cpu(shdr->CreditRequest);
/* result already set, check signature */
if (server->sign) {
int rc;
smb2_async_readv(struct cifs_readdata *rdata)
{
int rc, flags = 0;
- struct smb2_hdr *buf;
+ char *buf;
+ struct smb2_sync_hdr *shdr;
struct cifs_io_parms io_parms;
struct smb_rqst rqst = { .rq_iov = &rdata->iov,
.rq_nvec = 1 };
return rc;
}
- buf = (struct smb2_hdr *)rdata->iov.iov_base;
+ buf = rdata->iov.iov_base;
+ shdr = get_sync_hdr(buf);
/* 4 for rfc1002 length field */
rdata->iov.iov_len = get_rfc1002_length(rdata->iov.iov_base) + 4;
if (rdata->credits) {
- buf->CreditCharge = cpu_to_le16(DIV_ROUND_UP(rdata->bytes,
+ shdr->CreditCharge = cpu_to_le16(DIV_ROUND_UP(rdata->bytes,
SMB2_MAX_BUFFER_SIZE));
- buf->CreditRequest = buf->CreditCharge;
+ shdr->CreditRequest = shdr->CreditCharge;
spin_lock(&server->req_lock);
server->credits += rdata->credits -
- le16_to_cpu(buf->CreditCharge);
+ le16_to_cpu(shdr->CreditCharge);
spin_unlock(&server->req_lock);
wake_up(&server->request_q);
flags = CIFS_HAS_CREDITS;
{
int resp_buftype, rc = -EACCES;
struct smb2_read_rsp *rsp = NULL;
+ struct smb2_sync_hdr *shdr;
struct kvec iov[1];
*nbytes = 0;
&resp_buftype, CIFS_LOG_ERROR);
rsp = (struct smb2_read_rsp *)iov[0].iov_base;
+ shdr = get_sync_hdr(rsp);
- if (rsp->hdr.Status == STATUS_END_OF_FILE) {
+ if (shdr->Status == STATUS_END_OF_FILE) {
free_rsp_buf(resp_buftype, iov[0].iov_base);
return 0;
}
}
if (*buf) {
- memcpy(*buf, (char *)&rsp->hdr.ProtocolId + rsp->DataOffset,
- *nbytes);
+ memcpy(*buf, (char *)shdr + rsp->DataOffset, *nbytes);
free_rsp_buf(resp_buftype, iov[0].iov_base);
} else if (resp_buftype != CIFS_NO_BUFFER) {
*buf = iov[0].iov_base;
switch (mid->mid_state) {
case MID_RESPONSE_RECEIVED:
- credits_received = le16_to_cpu(rsp->hdr.CreditRequest);
+ credits_received = le16_to_cpu(rsp->hdr.sync_hdr.CreditRequest);
wdata->result = smb2_check_receive(mid, tcon->ses->server, 0);
if (wdata->result != 0)
break;
{
int rc = -EACCES, flags = 0;
struct smb2_write_req *req = NULL;
+ struct smb2_sync_hdr *shdr;
struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
struct TCP_Server_Info *server = tcon->ses->server;
struct kvec iov;
goto async_writev_out;
}
- req->hdr.ProcessId = cpu_to_le32(wdata->cfile->pid);
+ shdr = get_sync_hdr(req);
+ shdr->ProcessId = cpu_to_le32(wdata->cfile->pid);
req->PersistentFileId = wdata->cfile->fid.persistent_fid;
req->VolatileFileId = wdata->cfile->fid.volatile_fid;
inc_rfc1001_len(&req->hdr, wdata->bytes - 1 /* Buffer */);
if (wdata->credits) {
- req->hdr.CreditCharge = cpu_to_le16(DIV_ROUND_UP(wdata->bytes,
+ shdr->CreditCharge = cpu_to_le16(DIV_ROUND_UP(wdata->bytes,
SMB2_MAX_BUFFER_SIZE));
- req->hdr.CreditRequest = req->hdr.CreditCharge;
+ shdr->CreditRequest = shdr->CreditCharge;
spin_lock(&server->req_lock);
server->credits += wdata->credits -
- le16_to_cpu(req->hdr.CreditCharge);
+ le16_to_cpu(shdr->CreditCharge);
spin_unlock(&server->req_lock);
wake_up(&server->request_q);
flags = CIFS_HAS_CREDITS;
if (io_parms->tcon->ses->server == NULL)
return -ECONNABORTED;
- req->hdr.ProcessId = cpu_to_le32(io_parms->pid);
+ req->hdr.sync_hdr.ProcessId = cpu_to_le32(io_parms->pid);
req->PersistentFileId = io_parms->persistent_fid;
req->VolatileFileId = io_parms->volatile_fid;
rsp = (struct smb2_query_directory_rsp *)iov[0].iov_base;
if (rc) {
- if (rc == -ENODATA && rsp->hdr.Status == STATUS_NO_MORE_FILES) {
+ if (rc == -ENODATA &&
+ rsp->hdr.sync_hdr.Status == STATUS_NO_MORE_FILES) {
srch_inf->endOfSearch = true;
rc = 0;
}
return rc;
}
- req->hdr.ProcessId = cpu_to_le32(pid);
+ req->hdr.sync_hdr.ProcessId = cpu_to_le32(pid);
req->InfoType = SMB2_O_INFO_FILE;
req->FileInfoClass = info_class;
req->VolatileFid = volatile_fid;
req->PersistentFid = persistent_fid;
req->OplockLevel = oplock_level;
- req->hdr.CreditRequest = cpu_to_le16(1);
+ req->hdr.sync_hdr.CreditRequest = cpu_to_le16(1);
rc = SendReceiveNoRsp(xid, tcon->ses, (char *) req, CIFS_OBREAK_OP);
/* SMB2 buffer freed by function above */
if (rc)
return rc;
- req->hdr.ProcessId = cpu_to_le32(pid);
+ req->hdr.sync_hdr.ProcessId = cpu_to_le32(pid);
req->LockCount = cpu_to_le16(num_lock);
req->PersistentFileId = persist_fid;
if (rc)
return rc;
- req->hdr.CreditRequest = cpu_to_le16(1);
+ req->hdr.sync_hdr.CreditRequest = cpu_to_le16(1);
req->StructureSize = cpu_to_le16(36);
inc_rfc1001_len(req, 12);
#define SMB2_HEADER_STRUCTURE_SIZE cpu_to_le16(64)
-struct smb2_hdr {
- __be32 smb2_buf_length; /* big endian on wire */
- /* length is only two or three bytes - with
- one or two byte type preceding it that MBZ */
+struct smb2_sync_hdr {
__le32 ProtocolId; /* 0xFE 'S' 'M' 'B' */
__le16 StructureSize; /* 64 */
__le16 CreditCharge; /* MBZ */
__u8 Signature[16];
} __packed;
+struct smb2_hdr {
+ __be32 smb2_buf_length; /* big endian on wire */
+ /* length is only two or three bytes - with */
+ /* one or two byte type preceding it that MBZ */
+ struct smb2_sync_hdr sync_hdr;
+} __packed;
+
struct smb2_pdu {
struct smb2_hdr hdr;
__le16 StructureSize2; /* size of wct area (varies, request specific) */
}
static struct cifs_ses *
-smb2_find_smb_ses(struct smb2_hdr *smb2hdr, struct TCP_Server_Info *server)
+smb2_find_smb_ses(struct smb2_sync_hdr *shdr, struct TCP_Server_Info *server)
{
struct cifs_ses *ses;
spin_lock(&cifs_tcp_ses_lock);
list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
- if (ses->Suid != smb2hdr->SessionId)
+ if (ses->Suid != shdr->SessionId)
continue;
spin_unlock(&cifs_tcp_ses_lock);
return ses;
return NULL;
}
-
int
smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server)
{
unsigned char smb2_signature[SMB2_HMACSHA256_SIZE];
unsigned char *sigptr = smb2_signature;
struct kvec *iov = rqst->rq_iov;
- struct smb2_hdr *smb2_pdu = (struct smb2_hdr *)iov[0].iov_base;
+ struct smb2_sync_hdr *shdr = get_sync_hdr(iov[0].iov_base);
struct cifs_ses *ses;
- ses = smb2_find_smb_ses(smb2_pdu, server);
+ ses = smb2_find_smb_ses(shdr, server);
if (!ses) {
cifs_dbg(VFS, "%s: Could not find session\n", __func__);
return 0;
}
memset(smb2_signature, 0x0, SMB2_HMACSHA256_SIZE);
- memset(smb2_pdu->Signature, 0x0, SMB2_SIGNATURE_SIZE);
+ memset(shdr->Signature, 0x0, SMB2_SIGNATURE_SIZE);
rc = smb2_crypto_shash_allocate(server);
if (rc) {
&server->secmech.sdeschmacsha256->shash);
if (!rc)
- memcpy(smb2_pdu->Signature, sigptr, SMB2_SIGNATURE_SIZE);
+ memcpy(shdr->Signature, sigptr, SMB2_SIGNATURE_SIZE);
return rc;
}
unsigned char smb3_signature[SMB2_CMACAES_SIZE];
unsigned char *sigptr = smb3_signature;
struct kvec *iov = rqst->rq_iov;
- struct smb2_hdr *smb2_pdu = (struct smb2_hdr *)iov[0].iov_base;
+ struct smb2_sync_hdr *shdr = get_sync_hdr(iov[0].iov_base);
struct cifs_ses *ses;
- ses = smb2_find_smb_ses(smb2_pdu, server);
+ ses = smb2_find_smb_ses(shdr, server);
if (!ses) {
cifs_dbg(VFS, "%s: Could not find session\n", __func__);
return 0;
}
memset(smb3_signature, 0x0, SMB2_CMACAES_SIZE);
- memset(smb2_pdu->Signature, 0x0, SMB2_SIGNATURE_SIZE);
+ memset(shdr->Signature, 0x0, SMB2_SIGNATURE_SIZE);
rc = crypto_shash_setkey(server->secmech.cmacaes,
ses->smb3signingkey, SMB2_CMACAES_SIZE);
&server->secmech.sdesccmacaes->shash);
if (!rc)
- memcpy(smb2_pdu->Signature, sigptr, SMB2_SIGNATURE_SIZE);
+ memcpy(shdr->Signature, sigptr, SMB2_SIGNATURE_SIZE);
return rc;
}
smb2_sign_rqst(struct smb_rqst *rqst, struct TCP_Server_Info *server)
{
int rc = 0;
- struct smb2_hdr *smb2_pdu = rqst->rq_iov[0].iov_base;
+ struct smb2_sync_hdr *shdr = get_sync_hdr(rqst->rq_iov[0].iov_base);
- if (!(smb2_pdu->Flags & SMB2_FLAGS_SIGNED) ||
+ if (!(shdr->Flags & SMB2_FLAGS_SIGNED) ||
server->tcpStatus == CifsNeedNegotiate)
return rc;
if (!server->session_estab) {
- strncpy(smb2_pdu->Signature, "BSRSPYL", 8);
+ strncpy(shdr->Signature, "BSRSPYL", 8);
return rc;
}
{
unsigned int rc;
char server_response_sig[16];
- struct smb2_hdr *smb2_pdu = (struct smb2_hdr *)rqst->rq_iov[0].iov_base;
+ struct smb2_sync_hdr *shdr = get_sync_hdr(rqst->rq_iov[0].iov_base);
- if ((smb2_pdu->Command == SMB2_NEGOTIATE) ||
- (smb2_pdu->Command == SMB2_SESSION_SETUP) ||
- (smb2_pdu->Command == SMB2_OPLOCK_BREAK) ||
+ if ((shdr->Command == SMB2_NEGOTIATE) ||
+ (shdr->Command == SMB2_SESSION_SETUP) ||
+ (shdr->Command == SMB2_OPLOCK_BREAK) ||
(!server->session_estab))
return 0;
*/
/* Do not need to verify session setups with signature "BSRSPYL " */
- if (memcmp(smb2_pdu->Signature, "BSRSPYL ", 8) == 0)
+ if (memcmp(shdr->Signature, "BSRSPYL ", 8) == 0)
cifs_dbg(FYI, "dummy signature received for smb command 0x%x\n",
- smb2_pdu->Command);
+ shdr->Command);
/*
* Save off the origiginal signature so we can modify the smb and check
* our calculated signature against what the server sent.
*/
- memcpy(server_response_sig, smb2_pdu->Signature, SMB2_SIGNATURE_SIZE);
+ memcpy(server_response_sig, shdr->Signature, SMB2_SIGNATURE_SIZE);
- memset(smb2_pdu->Signature, 0, SMB2_SIGNATURE_SIZE);
+ memset(shdr->Signature, 0, SMB2_SIGNATURE_SIZE);
mutex_lock(&server->srv_mutex);
rc = server->ops->calc_signature(rqst, server);
if (rc)
return rc;
- if (memcmp(server_response_sig, smb2_pdu->Signature,
- SMB2_SIGNATURE_SIZE))
+ if (memcmp(server_response_sig, shdr->Signature, SMB2_SIGNATURE_SIZE))
return -EACCES;
else
return 0;
* and when srv_mutex is held.
*/
static inline void
-smb2_seq_num_into_buf(struct TCP_Server_Info *server, struct smb2_hdr *hdr)
+smb2_seq_num_into_buf(struct TCP_Server_Info *server,
+ struct smb2_sync_hdr *shdr)
{
- unsigned int i, num = le16_to_cpu(hdr->CreditCharge);
+ unsigned int i, num = le16_to_cpu(shdr->CreditCharge);
- hdr->MessageId = get_next_mid64(server);
+ shdr->MessageId = get_next_mid64(server);
/* skip message numbers according to CreditCharge field */
for (i = 1; i < num; i++)
get_next_mid(server);
}
static struct mid_q_entry *
-smb2_mid_entry_alloc(const struct smb2_hdr *smb_buffer,
+smb2_mid_entry_alloc(const struct smb2_sync_hdr *shdr,
struct TCP_Server_Info *server)
{
struct mid_q_entry *temp;
return temp;
else {
memset(temp, 0, sizeof(struct mid_q_entry));
- temp->mid = le64_to_cpu(smb_buffer->MessageId);
+ temp->mid = le64_to_cpu(shdr->MessageId);
temp->pid = current->pid;
- temp->command = smb_buffer->Command; /* Always LE */
+ temp->command = shdr->Command; /* Always LE */
temp->when_alloc = jiffies;
temp->server = server;
}
static int
-smb2_get_mid_entry(struct cifs_ses *ses, struct smb2_hdr *buf,
+smb2_get_mid_entry(struct cifs_ses *ses, struct smb2_sync_hdr *shdr,
struct mid_q_entry **mid)
{
if (ses->server->tcpStatus == CifsExiting)
}
if (ses->status == CifsNew) {
- if ((buf->Command != SMB2_SESSION_SETUP) &&
- (buf->Command != SMB2_NEGOTIATE))
+ if ((shdr->Command != SMB2_SESSION_SETUP) &&
+ (shdr->Command != SMB2_NEGOTIATE))
return -EAGAIN;
/* else ok - we are setting up session */
}
if (ses->status == CifsExiting) {
- if (buf->Command != SMB2_LOGOFF)
+ if (shdr->Command != SMB2_LOGOFF)
return -EAGAIN;
/* else ok - we are shutting down the session */
}
- *mid = smb2_mid_entry_alloc(buf, ses->server);
+ *mid = smb2_mid_entry_alloc(shdr, ses->server);
if (*mid == NULL)
return -ENOMEM;
spin_lock(&GlobalMid_Lock);
smb2_setup_request(struct cifs_ses *ses, struct smb_rqst *rqst)
{
int rc;
- struct smb2_hdr *hdr = (struct smb2_hdr *)rqst->rq_iov[0].iov_base;
+ struct smb2_sync_hdr *shdr = get_sync_hdr(rqst->rq_iov[0].iov_base);
struct mid_q_entry *mid;
- smb2_seq_num_into_buf(ses->server, hdr);
+ smb2_seq_num_into_buf(ses->server, shdr);
- rc = smb2_get_mid_entry(ses, hdr, &mid);
+ rc = smb2_get_mid_entry(ses, shdr, &mid);
if (rc)
return ERR_PTR(rc);
rc = smb2_sign_rqst(rqst, ses->server);
smb2_setup_async_request(struct TCP_Server_Info *server, struct smb_rqst *rqst)
{
int rc;
- struct smb2_hdr *hdr = (struct smb2_hdr *)rqst->rq_iov[0].iov_base;
+ struct smb2_sync_hdr *shdr = get_sync_hdr(rqst->rq_iov[0].iov_base);
struct mid_q_entry *mid;
- smb2_seq_num_into_buf(server, hdr);
+ smb2_seq_num_into_buf(server, shdr);
- mid = smb2_mid_entry_alloc(hdr, server);
+ mid = smb2_mid_entry_alloc(shdr, server);
if (mid == NULL)
return ERR_PTR(-ENOMEM);