mirror of
https://github.com/samba-team/samba.git
synced 2025-08-26 01:49:31 +03:00
Convert SMB and SMB2 code to use a common buffer handling structure
This converts our SMB and SMB2 code to use a common structure "struct request_bufinfo" for information on the buffer bounds of a packet, alignment information and string handling. This allows us to use a common backend for SMB and SMB2 code, while still using all the same string and blob handling functions. Up to now we had been passing a NULL req handle into these common routines from the SMB2 side of the server, which meant that we failed any operation which did a bounds checked string extraction (such as a RenameInformation setinfo call, which is what Vista uses for renaming files) There is still some more work to be done on this - for example we can now remove many of the SMB2 specific buffer handling functions that we had, and use the SMB ones.
This commit is contained in:
@ -177,9 +177,9 @@ NTSTATUS smb_raw_sesssetup_recv(struct smbcli_request *req,
|
||||
parms->old.out.action = SVAL(req->in.vwv, VWV(2));
|
||||
p = req->in.data;
|
||||
if (p) {
|
||||
p += smbcli_req_pull_string(req, mem_ctx, &parms->old.out.os, p, -1, STR_TERMINATE);
|
||||
p += smbcli_req_pull_string(req, mem_ctx, &parms->old.out.lanman, p, -1, STR_TERMINATE);
|
||||
p += smbcli_req_pull_string(req, mem_ctx, &parms->old.out.domain, p, -1, STR_TERMINATE);
|
||||
p += smbcli_req_pull_string(&req->in.bufinfo, mem_ctx, &parms->old.out.os, p, -1, STR_TERMINATE);
|
||||
p += smbcli_req_pull_string(&req->in.bufinfo, mem_ctx, &parms->old.out.lanman, p, -1, STR_TERMINATE);
|
||||
p += smbcli_req_pull_string(&req->in.bufinfo, mem_ctx, &parms->old.out.domain, p, -1, STR_TERMINATE);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -190,10 +190,10 @@ NTSTATUS smb_raw_sesssetup_recv(struct smbcli_request *req,
|
||||
parms->nt1.out.action = SVAL(req->in.vwv, VWV(2));
|
||||
p = req->in.data;
|
||||
if (p) {
|
||||
p += smbcli_req_pull_string(req, mem_ctx, &parms->nt1.out.os, p, -1, STR_TERMINATE);
|
||||
p += smbcli_req_pull_string(req, mem_ctx, &parms->nt1.out.lanman, p, -1, STR_TERMINATE);
|
||||
p += smbcli_req_pull_string(&req->in.bufinfo, mem_ctx, &parms->nt1.out.os, p, -1, STR_TERMINATE);
|
||||
p += smbcli_req_pull_string(&req->in.bufinfo, mem_ctx, &parms->nt1.out.lanman, p, -1, STR_TERMINATE);
|
||||
if (p < (req->in.data + req->in.data_size)) {
|
||||
p += smbcli_req_pull_string(req, mem_ctx, &parms->nt1.out.domain, p, -1, STR_TERMINATE);
|
||||
p += smbcli_req_pull_string(&req->in.bufinfo, mem_ctx, &parms->nt1.out.domain, p, -1, STR_TERMINATE);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -209,11 +209,11 @@ NTSTATUS smb_raw_sesssetup_recv(struct smbcli_request *req,
|
||||
break;
|
||||
}
|
||||
|
||||
parms->spnego.out.secblob = smbcli_req_pull_blob(req, mem_ctx, p, len);
|
||||
parms->spnego.out.secblob = smbcli_req_pull_blob(&req->in.bufinfo, mem_ctx, p, len);
|
||||
p += parms->spnego.out.secblob.length;
|
||||
p += smbcli_req_pull_string(req, mem_ctx, &parms->spnego.out.os, p, -1, STR_TERMINATE);
|
||||
p += smbcli_req_pull_string(req, mem_ctx, &parms->spnego.out.lanman, p, -1, STR_TERMINATE);
|
||||
p += smbcli_req_pull_string(req, mem_ctx, &parms->spnego.out.workgroup, p, -1, STR_TERMINATE);
|
||||
p += smbcli_req_pull_string(&req->in.bufinfo, mem_ctx, &parms->spnego.out.os, p, -1, STR_TERMINATE);
|
||||
p += smbcli_req_pull_string(&req->in.bufinfo, mem_ctx, &parms->spnego.out.lanman, p, -1, STR_TERMINATE);
|
||||
p += smbcli_req_pull_string(&req->in.bufinfo, mem_ctx, &parms->spnego.out.workgroup, p, -1, STR_TERMINATE);
|
||||
break;
|
||||
|
||||
case RAW_SESSSETUP_SMB2:
|
||||
|
@ -444,6 +444,8 @@ static NTSTATUS smbcli_transport_finish_recv(void *private, DATA_BLOB blob)
|
||||
req->in.ptr = req->in.data;
|
||||
req->flags2 = SVAL(req->in.hdr, HDR_FLG2);
|
||||
|
||||
smb_setup_bufinfo(req);
|
||||
|
||||
if (!(req->flags2 & FLAGS2_32_BIT_ERROR_CODES)) {
|
||||
int class = CVAL(req->in.hdr,HDR_RCLS);
|
||||
int code = SVAL(req->in.hdr,HDR_ERR);
|
||||
@ -637,7 +639,7 @@ NTSTATUS smb_raw_echo_recv(struct smbcli_request *req, TALLOC_CTX *mem_ctx,
|
||||
p->out.data = talloc_array(mem_ctx, uint8_t, p->out.size);
|
||||
NT_STATUS_HAVE_NO_MEMORY(p->out.data);
|
||||
|
||||
if (!smbcli_raw_pull_data(req, req->in.data, p->out.size, p->out.data)) {
|
||||
if (!smbcli_raw_pull_data(&req->in.bufinfo, req->in.data, p->out.size, p->out.data)) {
|
||||
req->status = NT_STATUS_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
|
@ -123,9 +123,9 @@ NTSTATUS smb_raw_tcon_recv(struct smbcli_request *req, TALLOC_CTX *mem_ctx,
|
||||
p = req->in.data;
|
||||
if (!p) break;
|
||||
|
||||
p += smbcli_req_pull_string(req, mem_ctx, &parms->tconx.out.dev_type,
|
||||
p, -1, STR_ASCII | STR_TERMINATE);
|
||||
p += smbcli_req_pull_string(req, mem_ctx, &parms->tconx.out.fs_type,
|
||||
p += smbcli_req_pull_string(&req->in.bufinfo, mem_ctx, &parms->tconx.out.dev_type,
|
||||
p, -1, STR_ASCII | STR_TERMINATE);
|
||||
p += smbcli_req_pull_string(&req->in.bufinfo, mem_ctx, &parms->tconx.out.fs_type,
|
||||
p, -1, STR_TERMINATE);
|
||||
break;
|
||||
|
||||
|
@ -250,8 +250,8 @@ struct smbcli_request {
|
||||
/* the mid of this packet - used to match replies */
|
||||
uint16_t mid;
|
||||
|
||||
struct request_buffer in;
|
||||
struct request_buffer out;
|
||||
struct smb_request_buffer in;
|
||||
struct smb_request_buffer out;
|
||||
|
||||
/* information on what to do with a reply when it is received
|
||||
asyncronously. If this is not setup when a reply is received then
|
||||
|
@ -616,7 +616,7 @@ NTSTATUS smb_raw_open_recv(struct smbcli_request *req, TALLOC_CTX *mem_ctx, unio
|
||||
case RAW_OPEN_CTEMP:
|
||||
SMBCLI_CHECK_WCT(req, 1);
|
||||
parms->ctemp.out.file.fnum = SVAL(req->in.vwv, VWV(0));
|
||||
smbcli_req_pull_string(req, mem_ctx, &parms->ctemp.out.name, req->in.data, -1, STR_TERMINATE | STR_ASCII);
|
||||
smbcli_req_pull_string(&req->in.bufinfo, mem_ctx, &parms->ctemp.out.name, req->in.data, -1, STR_TERMINATE | STR_ASCII);
|
||||
break;
|
||||
|
||||
case RAW_OPEN_SPLOPEN:
|
||||
@ -675,7 +675,7 @@ NTSTATUS smb_raw_open_recv(struct smbcli_request *req, TALLOC_CTX *mem_ctx, unio
|
||||
parms->openxreadx.out.nread = SVAL(req->in.vwv, VWV(5));
|
||||
if (parms->openxreadx.out.nread >
|
||||
MAX(parms->openxreadx.in.mincnt, parms->openxreadx.in.maxcnt) ||
|
||||
!smbcli_raw_pull_data(req, req->in.hdr + SVAL(req->in.vwv, VWV(6)),
|
||||
!smbcli_raw_pull_data(&req->in.bufinfo, req->in.hdr + SVAL(req->in.vwv, VWV(6)),
|
||||
parms->openxreadx.out.nread,
|
||||
parms->openxreadx.out.data)) {
|
||||
req->status = NT_STATUS_BUFFER_TOO_SMALL;
|
||||
|
@ -59,7 +59,7 @@ static NTSTATUS smb_raw_smbioctl_recv(struct smbcli_request *req,
|
||||
return smbcli_request_destroy(req);
|
||||
}
|
||||
|
||||
parms->ioctl.out.blob = smbcli_req_pull_blob(req, mem_ctx, req->in.data, -1);
|
||||
parms->ioctl.out.blob = smbcli_req_pull_blob(&req->in.bufinfo, mem_ctx, req->in.data, -1);
|
||||
return smbcli_request_destroy(req);
|
||||
}
|
||||
|
||||
|
@ -135,14 +135,14 @@ NTSTATUS smb_raw_negotiate_recv(struct smbcli_request *req)
|
||||
if (req->in.data_size < 16) {
|
||||
goto failed;
|
||||
}
|
||||
transport->negotiate.server_guid = smbcli_req_pull_blob(req, transport, req->in.data, 16);
|
||||
transport->negotiate.secblob = smbcli_req_pull_blob(req, transport, req->in.data + 16, req->in.data_size - 16);
|
||||
transport->negotiate.server_guid = smbcli_req_pull_blob(&req->in.bufinfo, transport, req->in.data, 16);
|
||||
transport->negotiate.secblob = smbcli_req_pull_blob(&req->in.bufinfo, transport, req->in.data + 16, req->in.data_size - 16);
|
||||
} else {
|
||||
if (req->in.data_size < (transport->negotiate.key_len)) {
|
||||
goto failed;
|
||||
}
|
||||
transport->negotiate.secblob = smbcli_req_pull_blob(req, transport, req->in.data, transport->negotiate.key_len);
|
||||
smbcli_req_pull_string(req, transport, &transport->negotiate.server_domain,
|
||||
transport->negotiate.secblob = smbcli_req_pull_blob(&req->in.bufinfo, transport, req->in.data, transport->negotiate.key_len);
|
||||
smbcli_req_pull_string(&req->in.bufinfo, transport, &transport->negotiate.server_domain,
|
||||
req->in.data+transport->negotiate.key_len,
|
||||
req->in.data_size-transport->negotiate.key_len, STR_UNICODE|STR_NOALIGN);
|
||||
/* here comes the server name */
|
||||
@ -168,7 +168,7 @@ NTSTATUS smb_raw_negotiate_recv(struct smbcli_request *req)
|
||||
if ((SVAL(req->in.vwv,VWV(5)) & 0x2)) {
|
||||
transport->negotiate.writebraw_supported = 1;
|
||||
}
|
||||
transport->negotiate.secblob = smbcli_req_pull_blob(req, transport,
|
||||
transport->negotiate.secblob = smbcli_req_pull_blob(&req->in.bufinfo, transport,
|
||||
req->in.data, req->in.data_size);
|
||||
} else {
|
||||
/* the old core protocol */
|
||||
|
@ -137,7 +137,7 @@ NTSTATUS smb_raw_read_recv(struct smbcli_request *req, union smb_read *parms)
|
||||
SMBCLI_CHECK_WCT(req, 5);
|
||||
parms->lockread.out.nread = SVAL(req->in.vwv, VWV(0));
|
||||
if (parms->lockread.out.nread > parms->lockread.in.count ||
|
||||
!smbcli_raw_pull_data(req, req->in.data+3,
|
||||
!smbcli_raw_pull_data(&req->in.bufinfo, req->in.data+3,
|
||||
parms->lockread.out.nread, parms->lockread.out.data)) {
|
||||
req->status = NT_STATUS_BUFFER_TOO_SMALL;
|
||||
}
|
||||
@ -148,7 +148,7 @@ NTSTATUS smb_raw_read_recv(struct smbcli_request *req, union smb_read *parms)
|
||||
SMBCLI_CHECK_WCT(req, 5);
|
||||
parms->read.out.nread = SVAL(req->in.vwv, VWV(0));
|
||||
if (parms->read.out.nread > parms->read.in.count ||
|
||||
!smbcli_raw_pull_data(req, req->in.data+3,
|
||||
!smbcli_raw_pull_data(&req->in.bufinfo, req->in.data+3,
|
||||
parms->read.out.nread, parms->read.out.data)) {
|
||||
req->status = NT_STATUS_BUFFER_TOO_SMALL;
|
||||
}
|
||||
@ -175,7 +175,7 @@ NTSTATUS smb_raw_read_recv(struct smbcli_request *req, union smb_read *parms)
|
||||
}
|
||||
|
||||
if (parms->readx.out.nread > MAX(parms->readx.in.mincnt, parms->readx.in.maxcnt) ||
|
||||
!smbcli_raw_pull_data(req, req->in.hdr + SVAL(req->in.vwv, VWV(6)),
|
||||
!smbcli_raw_pull_data(&req->in.bufinfo, req->in.hdr + SVAL(req->in.vwv, VWV(6)),
|
||||
parms->readx.out.nread,
|
||||
parms->readx.out.data)) {
|
||||
req->status = NT_STATUS_BUFFER_TOO_SMALL;
|
||||
|
@ -34,6 +34,17 @@
|
||||
/* assume that a character will not consume more than 3 bytes per char */
|
||||
#define MAX_BYTES_PER_CHAR 3
|
||||
|
||||
/* setup the bufinfo used for strings and range checking */
|
||||
void smb_setup_bufinfo(struct smbcli_request *req)
|
||||
{
|
||||
req->in.bufinfo.mem_ctx = req;
|
||||
req->in.bufinfo.unicode = (req->flags2 & FLAGS2_UNICODE_STRINGS)?true:false;
|
||||
req->in.bufinfo.align_base = req->in.buffer;
|
||||
req->in.bufinfo.data = req->in.data;
|
||||
req->in.bufinfo.data_size = req->in.data_size;
|
||||
}
|
||||
|
||||
|
||||
/* destroy a request structure and return final status */
|
||||
NTSTATUS smbcli_request_destroy(struct smbcli_request *req)
|
||||
{
|
||||
@ -298,6 +309,9 @@ NTSTATUS smbcli_chained_advance(struct smbcli_request *req)
|
||||
req->in.data = req->in.vwv + 2 + req->in.wct * 2;
|
||||
req->in.data_size = SVAL(req->in.vwv, VWV(req->in.wct));
|
||||
|
||||
/* fix the bufinfo */
|
||||
smb_setup_bufinfo(req);
|
||||
|
||||
if (buffer + 3 + req->in.wct*2 + req->in.data_size >
|
||||
req->in.buffer + req->in.size) {
|
||||
return NT_STATUS_BUFFER_TOO_SMALL;
|
||||
@ -544,13 +558,13 @@ size_t smbcli_req_append_var_block(struct smbcli_request *req, const uint8_t *by
|
||||
on failure zero is returned and *dest is set to NULL, otherwise the number
|
||||
of bytes consumed in the packet is returned
|
||||
*/
|
||||
static size_t smbcli_req_pull_ucs2(struct smbcli_request *req, TALLOC_CTX *mem_ctx,
|
||||
static size_t smbcli_req_pull_ucs2(struct request_bufinfo *bufinfo, TALLOC_CTX *mem_ctx,
|
||||
char **dest, const uint8_t *src, int byte_len, uint_t flags)
|
||||
{
|
||||
int src_len, src_len2, alignment=0;
|
||||
ssize_t ret;
|
||||
|
||||
if (!(flags & STR_NOALIGN) && ucs2_align(req->in.buffer, src, flags)) {
|
||||
if (!(flags & STR_NOALIGN) && ucs2_align(bufinfo->align_base, src, flags)) {
|
||||
src++;
|
||||
alignment=1;
|
||||
if (byte_len != -1) {
|
||||
@ -558,7 +572,7 @@ static size_t smbcli_req_pull_ucs2(struct smbcli_request *req, TALLOC_CTX *mem_c
|
||||
}
|
||||
}
|
||||
|
||||
src_len = req->in.data_size - PTR_DIFF(src, req->in.data);
|
||||
src_len = bufinfo->data_size - PTR_DIFF(src, bufinfo->data);
|
||||
if (src_len < 0) {
|
||||
*dest = NULL;
|
||||
return 0;
|
||||
@ -597,13 +611,13 @@ static size_t smbcli_req_pull_ucs2(struct smbcli_request *req, TALLOC_CTX *mem_c
|
||||
on failure zero is returned and *dest is set to NULL, otherwise the number
|
||||
of bytes consumed in the packet is returned
|
||||
*/
|
||||
size_t smbcli_req_pull_ascii(struct smbcli_request *req, TALLOC_CTX *mem_ctx,
|
||||
size_t smbcli_req_pull_ascii(struct request_bufinfo *bufinfo, TALLOC_CTX *mem_ctx,
|
||||
char **dest, const uint8_t *src, int byte_len, uint_t flags)
|
||||
{
|
||||
int src_len, src_len2;
|
||||
ssize_t ret;
|
||||
|
||||
src_len = req->in.data_size - PTR_DIFF(src, req->in.data);
|
||||
src_len = bufinfo->data_size - PTR_DIFF(src, bufinfo->data);
|
||||
if (src_len < 0) {
|
||||
*dest = NULL;
|
||||
return 0;
|
||||
@ -640,15 +654,15 @@ size_t smbcli_req_pull_ascii(struct smbcli_request *req, TALLOC_CTX *mem_ctx,
|
||||
on failure zero is returned and *dest is set to NULL, otherwise the number
|
||||
of bytes consumed in the packet is returned
|
||||
*/
|
||||
size_t smbcli_req_pull_string(struct smbcli_request *req, TALLOC_CTX *mem_ctx,
|
||||
size_t smbcli_req_pull_string(struct request_bufinfo *bufinfo, TALLOC_CTX *mem_ctx,
|
||||
char **dest, const uint8_t *src, int byte_len, uint_t flags)
|
||||
{
|
||||
if (!(flags & STR_ASCII) &&
|
||||
(((flags & STR_UNICODE) || (req->flags2 & FLAGS2_UNICODE_STRINGS)))) {
|
||||
return smbcli_req_pull_ucs2(req, mem_ctx, dest, src, byte_len, flags);
|
||||
(((flags & STR_UNICODE) || bufinfo->unicode))) {
|
||||
return smbcli_req_pull_ucs2(bufinfo, mem_ctx, dest, src, byte_len, flags);
|
||||
}
|
||||
|
||||
return smbcli_req_pull_ascii(req, mem_ctx, dest, src, byte_len, flags);
|
||||
return smbcli_req_pull_ascii(bufinfo, mem_ctx, dest, src, byte_len, flags);
|
||||
}
|
||||
|
||||
|
||||
@ -658,11 +672,11 @@ size_t smbcli_req_pull_string(struct smbcli_request *req, TALLOC_CTX *mem_ctx,
|
||||
|
||||
if byte_len is -1 then limit the blob only by packet size
|
||||
*/
|
||||
DATA_BLOB smbcli_req_pull_blob(struct smbcli_request *req, TALLOC_CTX *mem_ctx, const uint8_t *src, int byte_len)
|
||||
DATA_BLOB smbcli_req_pull_blob(struct request_bufinfo *bufinfo, TALLOC_CTX *mem_ctx, const uint8_t *src, int byte_len)
|
||||
{
|
||||
int src_len;
|
||||
|
||||
src_len = req->in.data_size - PTR_DIFF(src, req->in.data);
|
||||
src_len = bufinfo->data_size - PTR_DIFF(src, bufinfo->data);
|
||||
|
||||
if (src_len < 0) {
|
||||
return data_blob(NULL, 0);
|
||||
@ -677,13 +691,13 @@ DATA_BLOB smbcli_req_pull_blob(struct smbcli_request *req, TALLOC_CTX *mem_ctx,
|
||||
|
||||
/* check that a lump of data in a request is within the bounds of the data section of
|
||||
the packet */
|
||||
static bool smbcli_req_data_oob(struct smbcli_request *req, const uint8_t *ptr, uint32_t count)
|
||||
static bool smbcli_req_data_oob(struct request_bufinfo *bufinfo, const uint8_t *ptr, uint32_t count)
|
||||
{
|
||||
/* be careful with wraparound! */
|
||||
if (ptr < req->in.data ||
|
||||
ptr >= req->in.data + req->in.data_size ||
|
||||
count > req->in.data_size ||
|
||||
ptr + count > req->in.data + req->in.data_size) {
|
||||
if (ptr < bufinfo->data ||
|
||||
ptr >= bufinfo->data + bufinfo->data_size ||
|
||||
count > bufinfo->data_size ||
|
||||
ptr + count > bufinfo->data + bufinfo->data_size) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -694,11 +708,11 @@ static bool smbcli_req_data_oob(struct smbcli_request *req, const uint8_t *ptr,
|
||||
|
||||
return false if any part is outside the data portion of the packet
|
||||
*/
|
||||
bool smbcli_raw_pull_data(struct smbcli_request *req, const uint8_t *src, int len, uint8_t *dest)
|
||||
bool smbcli_raw_pull_data(struct request_bufinfo *bufinfo, const uint8_t *src, int len, uint8_t *dest)
|
||||
{
|
||||
if (len == 0) return true;
|
||||
|
||||
if (smbcli_req_data_oob(req, src, len)) {
|
||||
if (smbcli_req_data_oob(bufinfo, src, len)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -54,7 +54,7 @@ static void smb_raw_search_backend(struct smbcli_request *req,
|
||||
search_data.search.write_time = raw_pull_dos_date(req->transport,
|
||||
p + 22);
|
||||
search_data.search.size = IVAL(p, 26);
|
||||
smbcli_req_pull_ascii(req, mem_ctx, &name, p+30, 13, STR_ASCII);
|
||||
smbcli_req_pull_ascii(&req->in.bufinfo, mem_ctx, &name, p+30, 13, STR_ASCII);
|
||||
search_data.search.name = name;
|
||||
if (!callback(private, &search_data)) {
|
||||
break;
|
||||
|
@ -22,11 +22,22 @@
|
||||
|
||||
#include "libcli/raw/signing.h"
|
||||
|
||||
/*
|
||||
buffer limit structure used by both SMB and SMB2
|
||||
*/
|
||||
struct request_bufinfo {
|
||||
TALLOC_CTX *mem_ctx;
|
||||
bool unicode;
|
||||
const uint8_t *align_base;
|
||||
const uint8_t *data;
|
||||
size_t data_size;
|
||||
};
|
||||
|
||||
/*
|
||||
Shared state structure between client and server, representing the basic packet.
|
||||
*/
|
||||
|
||||
struct request_buffer {
|
||||
struct smb_request_buffer {
|
||||
/* the raw SMB buffer, including the 4 byte length header */
|
||||
uint8_t *buffer;
|
||||
|
||||
@ -56,6 +67,9 @@ struct request_buffer {
|
||||
* a send packet is done we need to move this
|
||||
* pointer */
|
||||
uint8_t *ptr;
|
||||
|
||||
/* this is used to range check and align strings and buffers */
|
||||
struct request_bufinfo bufinfo;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -65,7 +65,7 @@ static bool smbcli_set_smb_signing_common(struct smbcli_transport *transport)
|
||||
return true;
|
||||
}
|
||||
|
||||
void mark_packet_signed(struct request_buffer *out)
|
||||
void mark_packet_signed(struct smb_request_buffer *out)
|
||||
{
|
||||
uint16_t flags2;
|
||||
flags2 = SVAL(out->hdr, HDR_FLG2);
|
||||
@ -101,7 +101,7 @@ bool signing_good(struct smb_signing_context *sign_info,
|
||||
return true;
|
||||
}
|
||||
|
||||
void sign_outgoing_message(struct request_buffer *out, DATA_BLOB *mac_key, unsigned int seq_num)
|
||||
void sign_outgoing_message(struct smb_request_buffer *out, DATA_BLOB *mac_key, unsigned int seq_num)
|
||||
{
|
||||
uint8_t calc_md5_mac[16];
|
||||
struct MD5Context md5_ctx;
|
||||
@ -133,7 +133,7 @@ void sign_outgoing_message(struct request_buffer *out, DATA_BLOB *mac_key, unsig
|
||||
Uncomment this to test if the remote server actually verifies signitures...*/
|
||||
}
|
||||
|
||||
bool check_signed_incoming_message(struct request_buffer *in, DATA_BLOB *mac_key, uint_t seq_num)
|
||||
bool check_signed_incoming_message(struct smb_request_buffer *in, DATA_BLOB *mac_key, uint_t seq_num)
|
||||
{
|
||||
bool good;
|
||||
uint8_t calc_md5_mac[16];
|
||||
|
@ -28,6 +28,21 @@
|
||||
#include "libcli/smb2/smb2_calls.h"
|
||||
#include "param/param.h"
|
||||
|
||||
/* fill in the bufinfo */
|
||||
void smb2_setup_bufinfo(struct smb2_request *req)
|
||||
{
|
||||
req->in.bufinfo.mem_ctx = req;
|
||||
req->in.bufinfo.unicode = true;
|
||||
req->in.bufinfo.align_base = req->in.buffer;
|
||||
if (req->in.dynamic) {
|
||||
req->in.bufinfo.data = req->in.dynamic;
|
||||
req->in.bufinfo.data_size = req->in.body_size - req->in.body_fixed;
|
||||
} else {
|
||||
req->in.bufinfo.data = NULL;
|
||||
req->in.bufinfo.data_size = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
initialise a smb2 request
|
||||
*/
|
||||
|
@ -19,6 +19,8 @@
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "libcli/raw/request.h"
|
||||
|
||||
struct smb2_options {
|
||||
uint32_t timeout;
|
||||
};
|
||||
@ -102,6 +104,9 @@ struct smb2_request_buffer {
|
||||
* this will be moved when some dynamic data is pushed
|
||||
*/
|
||||
uint8_t *dynamic;
|
||||
|
||||
/* this is used to range check and align strings and buffers */
|
||||
struct request_bufinfo bufinfo;
|
||||
};
|
||||
|
||||
|
||||
|
@ -216,6 +216,8 @@ static NTSTATUS smb2_transport_finish_recv(void *private, DATA_BLOB blob)
|
||||
}
|
||||
}
|
||||
|
||||
smb2_setup_bufinfo(req);
|
||||
|
||||
DEBUG(2, ("SMB2 RECV seqnum=0x%llx\n", (long long)req->seqnum));
|
||||
dump_data(5, req->in.body, req->in.body_size);
|
||||
|
||||
|
@ -78,7 +78,7 @@ NTSTATUS smbsrv_blob_fill_data(TALLOC_CTX *mem_ctx,
|
||||
/*
|
||||
pull a string from a blob in a trans2 request
|
||||
*/
|
||||
size_t smbsrv_blob_pull_string(struct smbsrv_request *req,
|
||||
size_t smbsrv_blob_pull_string(struct request_bufinfo *bufinfo,
|
||||
const DATA_BLOB *blob,
|
||||
uint16_t offset,
|
||||
const char **str,
|
||||
@ -92,7 +92,7 @@ size_t smbsrv_blob_pull_string(struct smbsrv_request *req,
|
||||
return 0;
|
||||
}
|
||||
|
||||
return req_pull_string(req, str,
|
||||
return req_pull_string(bufinfo, str,
|
||||
blob->data + offset,
|
||||
blob->length - offset,
|
||||
STR_NO_RANGE_CHECK | flags);
|
||||
@ -521,7 +521,7 @@ NTSTATUS smbsrv_pull_passthru_sfileinfo(TALLOC_CTX *mem_ctx,
|
||||
union smb_setfileinfo *st,
|
||||
const DATA_BLOB *blob,
|
||||
int default_str_flags,
|
||||
struct smbsrv_request *req)
|
||||
struct request_bufinfo *bufinfo)
|
||||
{
|
||||
uint32_t len;
|
||||
DATA_BLOB str_blob;
|
||||
@ -560,12 +560,8 @@ NTSTATUS smbsrv_pull_passthru_sfileinfo(TALLOC_CTX *mem_ctx,
|
||||
return NT_STATUS_OK;
|
||||
|
||||
case RAW_SFILEINFO_RENAME_INFORMATION:
|
||||
if (!req) {
|
||||
/*
|
||||
* TODO: get rid of smbsrv_request argument of
|
||||
* smbsrv_blob_pull_string()
|
||||
*/
|
||||
return NT_STATUS_NOT_IMPLEMENTED;
|
||||
if (!bufinfo) {
|
||||
return NT_STATUS_INTERNAL_ERROR;
|
||||
}
|
||||
BLOB_CHECK_MIN_SIZE(blob, 12);
|
||||
|
||||
@ -574,7 +570,7 @@ NTSTATUS smbsrv_pull_passthru_sfileinfo(TALLOC_CTX *mem_ctx,
|
||||
len = IVAL(blob->data, 8);
|
||||
str_blob.data = blob->data+12;
|
||||
str_blob.length = MIN(blob->length, len);
|
||||
smbsrv_blob_pull_string(req, &str_blob, 0,
|
||||
smbsrv_blob_pull_string(bufinfo, &str_blob, 0,
|
||||
&st->rename_information.in.new_name,
|
||||
STR_UNICODE);
|
||||
if (st->rename_information.in.new_name == NULL) {
|
||||
|
@ -509,7 +509,7 @@ void smbsrv_reply_negprot(struct smbsrv_request *req)
|
||||
return;
|
||||
}
|
||||
protos[protos_count] = NULL;
|
||||
len = req_pull_ascii4(req, (const char **)&protos[protos_count], p, STR_ASCII|STR_TERMINATE);
|
||||
len = req_pull_ascii4(&req->in.bufinfo, (const char **)&protos[protos_count], p, STR_ASCII|STR_TERMINATE);
|
||||
p += len;
|
||||
if (len == 0 || !protos[protos_count]) break;
|
||||
|
||||
|
@ -134,7 +134,7 @@ static NTSTATUS nttrans_create(struct smbsrv_request *req,
|
||||
io->ntcreatex.in.sec_desc = NULL;
|
||||
io->ntcreatex.in.ea_list = NULL;
|
||||
|
||||
req_pull_string(req, &io->ntcreatex.in.fname,
|
||||
req_pull_string(&req->in.bufinfo, &io->ntcreatex.in.fname,
|
||||
params + 53,
|
||||
MIN(fname_len+1, trans->in.params.length - 53),
|
||||
STR_NO_RANGE_CHECK | STR_TERMINATE);
|
||||
@ -622,8 +622,8 @@ void smbsrv_reply_nttrans(struct smbsrv_request *req)
|
||||
memcpy(trans->in.setup, (char *)(req->in.vwv) + VWV(19),
|
||||
sizeof(uint16_t) * trans->in.setup_count);
|
||||
|
||||
if (!req_pull_blob(req, req->in.hdr + param_ofs, param_count, &trans->in.params) ||
|
||||
!req_pull_blob(req, req->in.hdr + data_ofs, data_count, &trans->in.data)) {
|
||||
if (!req_pull_blob(&req->in.bufinfo, req->in.hdr + param_ofs, param_count, &trans->in.params) ||
|
||||
!req_pull_blob(&req->in.bufinfo, req->in.hdr + data_ofs, data_count, &trans->in.data)) {
|
||||
smbsrv_send_error(req, NT_STATUS_FOOBAR);
|
||||
return;
|
||||
}
|
||||
|
@ -151,6 +151,9 @@ NTSTATUS smbsrv_recv_smb_request(void *private, DATA_BLOB blob)
|
||||
|
||||
req->flags2 = SVAL(req->in.hdr, HDR_FLG2);
|
||||
|
||||
/* fix the bufinfo */
|
||||
smbsrv_setup_bufinfo(req);
|
||||
|
||||
if (!smbsrv_signing_check_incoming(req)) {
|
||||
smbsrv_send_error(req, NT_STATUS_ACCESS_DENIED);
|
||||
return NT_STATUS_OK;
|
||||
@ -620,6 +623,9 @@ void smbsrv_chain_reply(struct smbsrv_request *req)
|
||||
req->in.data_size = data_size;
|
||||
req->in.ptr = data;
|
||||
|
||||
/* fix the bufinfo */
|
||||
smbsrv_setup_bufinfo(req);
|
||||
|
||||
req->chain_count++;
|
||||
|
||||
SSVAL(req->out.vwv, VWV(0), chain_cmd);
|
||||
|
@ -58,9 +58,9 @@ void smbsrv_reply_tcon(struct smbsrv_request *req)
|
||||
con.tcon.level = RAW_TCON_TCON;
|
||||
|
||||
p = req->in.data;
|
||||
p += req_pull_ascii4(req, &con.tcon.in.service, p, STR_TERMINATE);
|
||||
p += req_pull_ascii4(req, &con.tcon.in.password, p, STR_TERMINATE);
|
||||
p += req_pull_ascii4(req, &con.tcon.in.dev, p, STR_TERMINATE);
|
||||
p += req_pull_ascii4(&req->in.bufinfo, &con.tcon.in.service, p, STR_TERMINATE);
|
||||
p += req_pull_ascii4(&req->in.bufinfo, &con.tcon.in.password, p, STR_TERMINATE);
|
||||
p += req_pull_ascii4(&req->in.bufinfo, &con.tcon.in.dev, p, STR_TERMINATE);
|
||||
|
||||
if (!con.tcon.in.service || !con.tcon.in.password || !con.tcon.in.dev) {
|
||||
smbsrv_send_error(req, NT_STATUS_INVALID_PARAMETER);
|
||||
@ -106,14 +106,14 @@ void smbsrv_reply_tcon_and_X(struct smbsrv_request *req)
|
||||
|
||||
p = req->in.data;
|
||||
|
||||
if (!req_pull_blob(req, p, passlen, &con.tconx.in.password)) {
|
||||
if (!req_pull_blob(&req->in.bufinfo, p, passlen, &con.tconx.in.password)) {
|
||||
smbsrv_send_error(req, NT_STATUS_ILL_FORMED_PASSWORD);
|
||||
return;
|
||||
}
|
||||
p += passlen;
|
||||
|
||||
p += req_pull_string(req, &con.tconx.in.path, p, -1, STR_TERMINATE);
|
||||
p += req_pull_string(req, &con.tconx.in.device, p, -1, STR_ASCII);
|
||||
p += req_pull_string(&req->in.bufinfo, &con.tconx.in.path, p, -1, STR_TERMINATE);
|
||||
p += req_pull_string(&req->in.bufinfo, &con.tconx.in.device, p, -1, STR_ASCII);
|
||||
|
||||
if (!con.tconx.in.path || !con.tconx.in.device) {
|
||||
smbsrv_send_error(req, NT_STATUS_BAD_DEVICE_TYPE);
|
||||
@ -223,7 +223,7 @@ void smbsrv_reply_chkpth(struct smbsrv_request *req)
|
||||
SMBSRV_TALLOC_IO_PTR(io, union smb_chkpath);
|
||||
SMBSRV_SETUP_NTVFS_REQUEST(reply_simple_send, NTVFS_ASYNC_STATE_MAY_ASYNC);
|
||||
|
||||
req_pull_ascii4(req, &io->chkpath.in.path, req->in.data, STR_TERMINATE);
|
||||
req_pull_ascii4(&req->in.bufinfo, &io->chkpath.in.path, req->in.data, STR_TERMINATE);
|
||||
|
||||
SMBSRV_CALL_NTVFS_BACKEND(ntvfs_chkpath(req->ntvfs, io));
|
||||
}
|
||||
@ -264,7 +264,7 @@ void smbsrv_reply_getatr(struct smbsrv_request *req)
|
||||
st->getattr.level = RAW_FILEINFO_GETATTR;
|
||||
|
||||
/* parse request */
|
||||
req_pull_ascii4(req, &st->getattr.in.file.path, req->in.data, STR_TERMINATE);
|
||||
req_pull_ascii4(&req->in.bufinfo, &st->getattr.in.file.path, req->in.data, STR_TERMINATE);
|
||||
if (!st->getattr.in.file.path) {
|
||||
smbsrv_send_error(req, NT_STATUS_OBJECT_NAME_NOT_FOUND);
|
||||
return;
|
||||
@ -290,7 +290,7 @@ void smbsrv_reply_setatr(struct smbsrv_request *req)
|
||||
st->setattr.in.attrib = SVAL(req->in.vwv, VWV(0));
|
||||
st->setattr.in.write_time = srv_pull_dos_date3(req->smb_conn, req->in.vwv + VWV(1));
|
||||
|
||||
req_pull_ascii4(req, &st->setattr.in.file.path, req->in.data, STR_TERMINATE);
|
||||
req_pull_ascii4(&req->in.bufinfo, &st->setattr.in.file.path, req->in.data, STR_TERMINATE);
|
||||
|
||||
if (!st->setattr.in.file.path) {
|
||||
smbsrv_send_error(req, NT_STATUS_OBJECT_NAME_NOT_FOUND);
|
||||
@ -379,7 +379,7 @@ void smbsrv_reply_open(struct smbsrv_request *req)
|
||||
oi->openold.in.open_mode = SVAL(req->in.vwv, VWV(0));
|
||||
oi->openold.in.search_attrs = SVAL(req->in.vwv, VWV(1));
|
||||
|
||||
req_pull_ascii4(req, &oi->openold.in.fname, req->in.data, STR_TERMINATE);
|
||||
req_pull_ascii4(&req->in.bufinfo, &oi->openold.in.fname, req->in.data, STR_TERMINATE);
|
||||
|
||||
if (!oi->openold.in.fname) {
|
||||
smbsrv_send_error(req, NT_STATUS_OBJECT_NAME_NOT_FOUND);
|
||||
@ -452,7 +452,7 @@ void smbsrv_reply_open_and_X(struct smbsrv_request *req)
|
||||
oi->openx.in.size = IVAL(req->in.vwv, VWV(9));
|
||||
oi->openx.in.timeout = IVAL(req->in.vwv, VWV(11));
|
||||
|
||||
req_pull_ascii4(req, &oi->openx.in.fname, req->in.data, STR_TERMINATE);
|
||||
req_pull_ascii4(&req->in.bufinfo, &oi->openx.in.fname, req->in.data, STR_TERMINATE);
|
||||
|
||||
if (!oi->openx.in.fname) {
|
||||
smbsrv_send_error(req, NT_STATUS_OBJECT_NAME_NOT_FOUND);
|
||||
@ -502,7 +502,7 @@ void smbsrv_reply_mknew(struct smbsrv_request *req)
|
||||
oi->mknew.in.attrib = SVAL(req->in.vwv, VWV(0));
|
||||
oi->mknew.in.write_time = srv_pull_dos_date3(req->smb_conn, req->in.vwv + VWV(1));
|
||||
|
||||
req_pull_ascii4(req, &oi->mknew.in.fname, req->in.data, STR_TERMINATE);
|
||||
req_pull_ascii4(&req->in.bufinfo, &oi->mknew.in.fname, req->in.data, STR_TERMINATE);
|
||||
|
||||
if (!oi->mknew.in.fname) {
|
||||
smbsrv_send_error(req, NT_STATUS_OBJECT_NAME_NOT_FOUND);
|
||||
@ -551,7 +551,7 @@ void smbsrv_reply_ctemp(struct smbsrv_request *req)
|
||||
|
||||
/* the filename is actually a directory name, the server provides a filename
|
||||
in that directory */
|
||||
req_pull_ascii4(req, &oi->ctemp.in.directory, req->in.data, STR_TERMINATE);
|
||||
req_pull_ascii4(&req->in.bufinfo, &oi->ctemp.in.directory, req->in.data, STR_TERMINATE);
|
||||
|
||||
if (!oi->ctemp.in.directory) {
|
||||
smbsrv_send_error(req, NT_STATUS_OBJECT_NAME_NOT_FOUND);
|
||||
@ -576,7 +576,7 @@ void smbsrv_reply_unlink(struct smbsrv_request *req)
|
||||
|
||||
unl->unlink.in.attrib = SVAL(req->in.vwv, VWV(0));
|
||||
|
||||
req_pull_ascii4(req, &unl->unlink.in.pattern, req->in.data, STR_TERMINATE);
|
||||
req_pull_ascii4(&req->in.bufinfo, &unl->unlink.in.pattern, req->in.data, STR_TERMINATE);
|
||||
|
||||
SMBSRV_CALL_NTVFS_BACKEND(ntvfs_unlink(req->ntvfs, unl));
|
||||
}
|
||||
@ -958,7 +958,7 @@ void smbsrv_reply_write(struct smbsrv_request *req)
|
||||
io->write.in.data = req->in.data + 3;
|
||||
|
||||
/* make sure they gave us the data they promised */
|
||||
if (req_data_oob(req, io->write.in.data, io->write.in.count)) {
|
||||
if (req_data_oob(&req->in.bufinfo, io->write.in.data, io->write.in.count)) {
|
||||
smbsrv_send_error(req, NT_STATUS_FOOBAR);
|
||||
return;
|
||||
}
|
||||
@ -1027,7 +1027,7 @@ void smbsrv_reply_write_and_X(struct smbsrv_request *req)
|
||||
}
|
||||
|
||||
/* make sure the data is in bounds */
|
||||
if (req_data_oob(req, io->writex.in.data, io->writex.in.count)) {
|
||||
if (req_data_oob(&req->in.bufinfo, io->writex.in.data, io->writex.in.count)) {
|
||||
smbsrv_send_error(req, NT_STATUS_FOOBAR);
|
||||
return;
|
||||
}
|
||||
@ -1163,7 +1163,7 @@ void smbsrv_reply_writeclose(struct smbsrv_request *req)
|
||||
io->writeclose.in.data = req->in.data + 1;
|
||||
|
||||
/* make sure they gave us the data they promised */
|
||||
if (req_data_oob(req, io->writeclose.in.data, io->writeclose.in.count)) {
|
||||
if (req_data_oob(&req->in.bufinfo, io->writeclose.in.data, io->writeclose.in.count)) {
|
||||
smbsrv_send_error(req, NT_STATUS_FOOBAR);
|
||||
return;
|
||||
}
|
||||
@ -1313,7 +1313,7 @@ void smbsrv_reply_printopen(struct smbsrv_request *req)
|
||||
oi->splopen.in.setup_length = SVAL(req->in.vwv, VWV(0));
|
||||
oi->splopen.in.mode = SVAL(req->in.vwv, VWV(1));
|
||||
|
||||
req_pull_ascii4(req, &oi->splopen.in.ident, req->in.data, STR_TERMINATE);
|
||||
req_pull_ascii4(&req->in.bufinfo, &oi->splopen.in.ident, req->in.data, STR_TERMINATE);
|
||||
|
||||
SMBSRV_CALL_NTVFS_BACKEND(ntvfs_open(req->ntvfs, oi));
|
||||
}
|
||||
@ -1426,7 +1426,7 @@ void smbsrv_reply_printwrite(struct smbsrv_request *req)
|
||||
io->splwrite.in.data = req->in.data + 3;
|
||||
|
||||
/* make sure they gave us the data they promised */
|
||||
if (req_data_oob(req, io->splwrite.in.data, io->splwrite.in.count)) {
|
||||
if (req_data_oob(&req->in.bufinfo, io->splwrite.in.data, io->splwrite.in.count)) {
|
||||
smbsrv_send_error(req, NT_STATUS_FOOBAR);
|
||||
return;
|
||||
}
|
||||
@ -1449,7 +1449,7 @@ void smbsrv_reply_mkdir(struct smbsrv_request *req)
|
||||
SMBSRV_SETUP_NTVFS_REQUEST(reply_simple_send, NTVFS_ASYNC_STATE_MAY_ASYNC);
|
||||
|
||||
io->generic.level = RAW_MKDIR_MKDIR;
|
||||
req_pull_ascii4(req, &io->mkdir.in.path, req->in.data, STR_TERMINATE);
|
||||
req_pull_ascii4(&req->in.bufinfo, &io->mkdir.in.path, req->in.data, STR_TERMINATE);
|
||||
|
||||
SMBSRV_CALL_NTVFS_BACKEND(ntvfs_mkdir(req->ntvfs, io));
|
||||
}
|
||||
@ -1467,7 +1467,7 @@ void smbsrv_reply_rmdir(struct smbsrv_request *req)
|
||||
SMBSRV_TALLOC_IO_PTR(io, struct smb_rmdir);
|
||||
SMBSRV_SETUP_NTVFS_REQUEST(reply_simple_send, NTVFS_ASYNC_STATE_MAY_ASYNC);
|
||||
|
||||
req_pull_ascii4(req, &io->in.path, req->in.data, STR_TERMINATE);
|
||||
req_pull_ascii4(&req->in.bufinfo, &io->in.path, req->in.data, STR_TERMINATE);
|
||||
|
||||
SMBSRV_CALL_NTVFS_BACKEND(ntvfs_rmdir(req->ntvfs, io));
|
||||
}
|
||||
@ -1490,8 +1490,8 @@ void smbsrv_reply_mv(struct smbsrv_request *req)
|
||||
io->rename.in.attrib = SVAL(req->in.vwv, VWV(0));
|
||||
|
||||
p = req->in.data;
|
||||
p += req_pull_ascii4(req, &io->rename.in.pattern1, p, STR_TERMINATE);
|
||||
p += req_pull_ascii4(req, &io->rename.in.pattern2, p, STR_TERMINATE);
|
||||
p += req_pull_ascii4(&req->in.bufinfo, &io->rename.in.pattern1, p, STR_TERMINATE);
|
||||
p += req_pull_ascii4(&req->in.bufinfo, &io->rename.in.pattern2, p, STR_TERMINATE);
|
||||
|
||||
if (!io->rename.in.pattern1 || !io->rename.in.pattern2) {
|
||||
smbsrv_send_error(req, NT_STATUS_FOOBAR);
|
||||
@ -1521,8 +1521,8 @@ void smbsrv_reply_ntrename(struct smbsrv_request *req)
|
||||
io->ntrename.in.cluster_size = IVAL(req->in.vwv, VWV(2));
|
||||
|
||||
p = req->in.data;
|
||||
p += req_pull_ascii4(req, &io->ntrename.in.old_name, p, STR_TERMINATE);
|
||||
p += req_pull_ascii4(req, &io->ntrename.in.new_name, p, STR_TERMINATE);
|
||||
p += req_pull_ascii4(&req->in.bufinfo, &io->ntrename.in.old_name, p, STR_TERMINATE);
|
||||
p += req_pull_ascii4(&req->in.bufinfo, &io->ntrename.in.new_name, p, STR_TERMINATE);
|
||||
|
||||
if (!io->ntrename.in.old_name || !io->ntrename.in.new_name) {
|
||||
smbsrv_send_error(req, NT_STATUS_FOOBAR);
|
||||
@ -1568,8 +1568,8 @@ void smbsrv_reply_copy(struct smbsrv_request *req)
|
||||
cp->in.flags = SVAL(req->in.vwv, VWV(2));
|
||||
|
||||
p = req->in.data;
|
||||
p += req_pull_ascii4(req, &cp->in.path1, p, STR_TERMINATE);
|
||||
p += req_pull_ascii4(req, &cp->in.path2, p, STR_TERMINATE);
|
||||
p += req_pull_ascii4(&req->in.bufinfo, &cp->in.path1, p, STR_TERMINATE);
|
||||
p += req_pull_ascii4(&req->in.bufinfo, &cp->in.path2, p, STR_TERMINATE);
|
||||
|
||||
if (!cp->in.path1 || !cp->in.path2) {
|
||||
smbsrv_send_error(req, NT_STATUS_FOOBAR);
|
||||
@ -1638,7 +1638,7 @@ void smbsrv_reply_lockingX(struct smbsrv_request *req)
|
||||
}
|
||||
|
||||
/* make sure we got the promised data */
|
||||
if (req_data_oob(req, req->in.data, total_locks * lck_size)) {
|
||||
if (req_data_oob(&req->in.bufinfo, req->in.data, total_locks * lck_size)) {
|
||||
smbsrv_send_error(req, NT_STATUS_FOOBAR);
|
||||
return;
|
||||
}
|
||||
@ -1877,22 +1877,22 @@ static void reply_sesssetup_old(struct smbsrv_request *req)
|
||||
passlen = SVAL(req->in.vwv, VWV(7));
|
||||
|
||||
/* check the request isn't malformed */
|
||||
if (req_data_oob(req, req->in.data, passlen)) {
|
||||
if (req_data_oob(&req->in.bufinfo, req->in.data, passlen)) {
|
||||
smbsrv_send_error(req, NT_STATUS_FOOBAR);
|
||||
return;
|
||||
}
|
||||
|
||||
p = req->in.data;
|
||||
if (!req_pull_blob(req, p, passlen, &io->old.in.password)) {
|
||||
if (!req_pull_blob(&req->in.bufinfo, p, passlen, &io->old.in.password)) {
|
||||
smbsrv_send_error(req, NT_STATUS_FOOBAR);
|
||||
return;
|
||||
}
|
||||
p += passlen;
|
||||
|
||||
p += req_pull_string(req, &io->old.in.user, p, -1, STR_TERMINATE);
|
||||
p += req_pull_string(req, &io->old.in.domain, p, -1, STR_TERMINATE);
|
||||
p += req_pull_string(req, &io->old.in.os, p, -1, STR_TERMINATE);
|
||||
p += req_pull_string(req, &io->old.in.lanman, p, -1, STR_TERMINATE);
|
||||
p += req_pull_string(&req->in.bufinfo, &io->old.in.user, p, -1, STR_TERMINATE);
|
||||
p += req_pull_string(&req->in.bufinfo, &io->old.in.domain, p, -1, STR_TERMINATE);
|
||||
p += req_pull_string(&req->in.bufinfo, &io->old.in.os, p, -1, STR_TERMINATE);
|
||||
p += req_pull_string(&req->in.bufinfo, &io->old.in.lanman, p, -1, STR_TERMINATE);
|
||||
|
||||
/* call the generic handler */
|
||||
smbsrv_sesssetup_backend(req, io);
|
||||
@ -1921,28 +1921,28 @@ static void reply_sesssetup_nt1(struct smbsrv_request *req)
|
||||
io->nt1.in.capabilities = IVAL(req->in.vwv, VWV(11));
|
||||
|
||||
/* check the request isn't malformed */
|
||||
if (req_data_oob(req, req->in.data, passlen1) ||
|
||||
req_data_oob(req, req->in.data + passlen1, passlen2)) {
|
||||
if (req_data_oob(&req->in.bufinfo, req->in.data, passlen1) ||
|
||||
req_data_oob(&req->in.bufinfo, req->in.data + passlen1, passlen2)) {
|
||||
smbsrv_send_error(req, NT_STATUS_FOOBAR);
|
||||
return;
|
||||
}
|
||||
|
||||
p = req->in.data;
|
||||
if (!req_pull_blob(req, p, passlen1, &io->nt1.in.password1)) {
|
||||
if (!req_pull_blob(&req->in.bufinfo, p, passlen1, &io->nt1.in.password1)) {
|
||||
smbsrv_send_error(req, NT_STATUS_FOOBAR);
|
||||
return;
|
||||
}
|
||||
p += passlen1;
|
||||
if (!req_pull_blob(req, p, passlen2, &io->nt1.in.password2)) {
|
||||
if (!req_pull_blob(&req->in.bufinfo, p, passlen2, &io->nt1.in.password2)) {
|
||||
smbsrv_send_error(req, NT_STATUS_FOOBAR);
|
||||
return;
|
||||
}
|
||||
p += passlen2;
|
||||
|
||||
p += req_pull_string(req, &io->nt1.in.user, p, -1, STR_TERMINATE);
|
||||
p += req_pull_string(req, &io->nt1.in.domain, p, -1, STR_TERMINATE);
|
||||
p += req_pull_string(req, &io->nt1.in.os, p, -1, STR_TERMINATE);
|
||||
p += req_pull_string(req, &io->nt1.in.lanman, p, -1, STR_TERMINATE);
|
||||
p += req_pull_string(&req->in.bufinfo, &io->nt1.in.user, p, -1, STR_TERMINATE);
|
||||
p += req_pull_string(&req->in.bufinfo, &io->nt1.in.domain, p, -1, STR_TERMINATE);
|
||||
p += req_pull_string(&req->in.bufinfo, &io->nt1.in.os, p, -1, STR_TERMINATE);
|
||||
p += req_pull_string(&req->in.bufinfo, &io->nt1.in.lanman, p, -1, STR_TERMINATE);
|
||||
|
||||
/* call the generic handler */
|
||||
smbsrv_sesssetup_backend(req, io);
|
||||
@ -1971,15 +1971,15 @@ static void reply_sesssetup_spnego(struct smbsrv_request *req)
|
||||
io->spnego.in.capabilities = IVAL(req->in.vwv, VWV(10));
|
||||
|
||||
p = req->in.data;
|
||||
if (!req_pull_blob(req, p, blob_len, &io->spnego.in.secblob)) {
|
||||
if (!req_pull_blob(&req->in.bufinfo, p, blob_len, &io->spnego.in.secblob)) {
|
||||
smbsrv_send_error(req, NT_STATUS_FOOBAR);
|
||||
return;
|
||||
}
|
||||
p += blob_len;
|
||||
|
||||
p += req_pull_string(req, &io->spnego.in.os, p, -1, STR_TERMINATE);
|
||||
p += req_pull_string(req, &io->spnego.in.lanman, p, -1, STR_TERMINATE);
|
||||
p += req_pull_string(req, &io->spnego.in.workgroup, p, -1, STR_TERMINATE);
|
||||
p += req_pull_string(&req->in.bufinfo, &io->spnego.in.os, p, -1, STR_TERMINATE);
|
||||
p += req_pull_string(&req->in.bufinfo, &io->spnego.in.lanman, p, -1, STR_TERMINATE);
|
||||
p += req_pull_string(&req->in.bufinfo, &io->spnego.in.workgroup, p, -1, STR_TERMINATE);
|
||||
|
||||
/* call the generic handler */
|
||||
smbsrv_sesssetup_backend(req, io);
|
||||
@ -2199,7 +2199,7 @@ void smbsrv_reply_ntcreate_and_X(struct smbsrv_request *req)
|
||||
fname_len++;
|
||||
}
|
||||
|
||||
req_pull_string(req, &io->ntcreatex.in.fname, req->in.data, fname_len, STR_TERMINATE);
|
||||
req_pull_string(&req->in.bufinfo, &io->ntcreatex.in.fname, req->in.data, fname_len, STR_TERMINATE);
|
||||
if (!io->ntcreatex.in.fname) {
|
||||
smbsrv_send_error(req, NT_STATUS_FOOBAR);
|
||||
return;
|
||||
|
@ -33,6 +33,17 @@
|
||||
/* we over allocate the data buffer to prevent too many realloc calls */
|
||||
#define REQ_OVER_ALLOCATION 0
|
||||
|
||||
/* setup the bufinfo used for strings and range checking */
|
||||
void smbsrv_setup_bufinfo(struct smbsrv_request *req)
|
||||
{
|
||||
req->in.bufinfo.mem_ctx = req;
|
||||
req->in.bufinfo.unicode = (req->flags2 & FLAGS2_UNICODE_STRINGS)?true:false;
|
||||
req->in.bufinfo.align_base = req->in.buffer;
|
||||
req->in.bufinfo.data = req->in.data;
|
||||
req->in.bufinfo.data_size = req->in.data_size;
|
||||
}
|
||||
|
||||
|
||||
static int smbsrv_request_destructor(struct smbsrv_request *req)
|
||||
{
|
||||
DLIST_REMOVE(req->smb_conn->requests, req);
|
||||
@ -461,13 +472,13 @@ size_t req_append_var_block(struct smbsrv_request *req,
|
||||
on failure zero is returned and *dest is set to NULL, otherwise the number
|
||||
of bytes consumed in the packet is returned
|
||||
*/
|
||||
static size_t req_pull_ucs2(struct smbsrv_request *req, const char **dest, const uint8_t *src, int byte_len, uint_t flags)
|
||||
static size_t req_pull_ucs2(struct request_bufinfo *bufinfo, const char **dest, const uint8_t *src, int byte_len, uint_t flags)
|
||||
{
|
||||
int src_len, src_len2, alignment=0;
|
||||
ssize_t ret;
|
||||
char *dest2;
|
||||
|
||||
if (!(flags & STR_NOALIGN) && ucs2_align(req->in.buffer, src, flags)) {
|
||||
if (!(flags & STR_NOALIGN) && ucs2_align(bufinfo->align_base, src, flags)) {
|
||||
src++;
|
||||
alignment=1;
|
||||
if (byte_len != -1) {
|
||||
@ -478,7 +489,7 @@ static size_t req_pull_ucs2(struct smbsrv_request *req, const char **dest, const
|
||||
if (flags & STR_NO_RANGE_CHECK) {
|
||||
src_len = byte_len;
|
||||
} else {
|
||||
src_len = req->in.data_size - PTR_DIFF(src, req->in.data);
|
||||
src_len = bufinfo->data_size - PTR_DIFF(src, bufinfo->data);
|
||||
if (byte_len != -1 && src_len > byte_len) {
|
||||
src_len = byte_len;
|
||||
}
|
||||
@ -491,11 +502,11 @@ static size_t req_pull_ucs2(struct smbsrv_request *req, const char **dest, const
|
||||
|
||||
src_len2 = utf16_len_n(src, src_len);
|
||||
if (src_len2 == 0) {
|
||||
*dest = talloc_strdup(req, "");
|
||||
*dest = talloc_strdup(bufinfo->mem_ctx, "");
|
||||
return src_len2 + alignment;
|
||||
}
|
||||
|
||||
ret = convert_string_talloc(req, lp_iconv_convenience(global_loadparm), CH_UTF16, CH_UNIX, src, src_len2, (void **)&dest2);
|
||||
ret = convert_string_talloc(bufinfo->mem_ctx, lp_iconv_convenience(global_loadparm), CH_UTF16, CH_UNIX, src, src_len2, (void **)&dest2);
|
||||
|
||||
if (ret == -1) {
|
||||
*dest = NULL;
|
||||
@ -519,7 +530,7 @@ static size_t req_pull_ucs2(struct smbsrv_request *req, const char **dest, const
|
||||
on failure zero is returned and *dest is set to NULL, otherwise the number
|
||||
of bytes consumed in the packet is returned
|
||||
*/
|
||||
static size_t req_pull_ascii(struct smbsrv_request *req, const char **dest, const uint8_t *src, int byte_len, uint_t flags)
|
||||
static size_t req_pull_ascii(struct request_bufinfo *bufinfo, const char **dest, const uint8_t *src, int byte_len, uint_t flags)
|
||||
{
|
||||
int src_len, src_len2;
|
||||
ssize_t ret;
|
||||
@ -528,7 +539,7 @@ static size_t req_pull_ascii(struct smbsrv_request *req, const char **dest, cons
|
||||
if (flags & STR_NO_RANGE_CHECK) {
|
||||
src_len = byte_len;
|
||||
} else {
|
||||
src_len = req->in.data_size - PTR_DIFF(src, req->in.data);
|
||||
src_len = bufinfo->data_size - PTR_DIFF(src, bufinfo->data);
|
||||
if (src_len < 0) {
|
||||
*dest = NULL;
|
||||
return 0;
|
||||
@ -544,7 +555,7 @@ static size_t req_pull_ascii(struct smbsrv_request *req, const char **dest, cons
|
||||
src_len2++;
|
||||
}
|
||||
|
||||
ret = convert_string_talloc(req, lp_iconv_convenience(global_loadparm), CH_DOS, CH_UNIX, src, src_len2, (void **)&dest2);
|
||||
ret = convert_string_talloc(bufinfo->mem_ctx, lp_iconv_convenience(global_loadparm), CH_DOS, CH_UNIX, src, src_len2, (void **)&dest2);
|
||||
|
||||
if (ret == -1) {
|
||||
*dest = NULL;
|
||||
@ -568,14 +579,14 @@ static size_t req_pull_ascii(struct smbsrv_request *req, const char **dest, cons
|
||||
on failure zero is returned and *dest is set to NULL, otherwise the number
|
||||
of bytes consumed in the packet is returned
|
||||
*/
|
||||
size_t req_pull_string(struct smbsrv_request *req, const char **dest, const uint8_t *src, int byte_len, uint_t flags)
|
||||
size_t req_pull_string(struct request_bufinfo *bufinfo, const char **dest, const uint8_t *src, int byte_len, uint_t flags)
|
||||
{
|
||||
if (!(flags & STR_ASCII) &&
|
||||
(((flags & STR_UNICODE) || (req->flags2 & FLAGS2_UNICODE_STRINGS)))) {
|
||||
return req_pull_ucs2(req, dest, src, byte_len, flags);
|
||||
(((flags & STR_UNICODE) || bufinfo->unicode))) {
|
||||
return req_pull_ucs2(bufinfo, dest, src, byte_len, flags);
|
||||
}
|
||||
|
||||
return req_pull_ascii(req, dest, src, byte_len, flags);
|
||||
return req_pull_ascii(bufinfo, dest, src, byte_len, flags);
|
||||
}
|
||||
|
||||
|
||||
@ -588,13 +599,13 @@ size_t req_pull_string(struct smbsrv_request *req, const char **dest, const uint
|
||||
on failure *dest is set to the zero length string. This seems to
|
||||
match win2000 behaviour
|
||||
*/
|
||||
size_t req_pull_ascii4(struct smbsrv_request *req, const char **dest, const uint8_t *src, uint_t flags)
|
||||
size_t req_pull_ascii4(struct request_bufinfo *bufinfo, const char **dest, const uint8_t *src, uint_t flags)
|
||||
{
|
||||
ssize_t ret;
|
||||
|
||||
if (PTR_DIFF(src, req->in.data) + 1 > req->in.data_size) {
|
||||
if (PTR_DIFF(src, bufinfo->data) + 1 > bufinfo->data_size) {
|
||||
/* win2000 treats this as the empty string! */
|
||||
(*dest) = talloc_strdup(req, "");
|
||||
(*dest) = talloc_strdup(bufinfo->mem_ctx, "");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -603,9 +614,9 @@ size_t req_pull_ascii4(struct smbsrv_request *req, const char **dest, const uint
|
||||
behaviour */
|
||||
src++;
|
||||
|
||||
ret = req_pull_string(req, dest, src, -1, flags);
|
||||
ret = req_pull_string(bufinfo, dest, src, -1, flags);
|
||||
if (ret == -1) {
|
||||
(*dest) = talloc_strdup(req, "");
|
||||
(*dest) = talloc_strdup(bufinfo->mem_ctx, "");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -617,30 +628,30 @@ size_t req_pull_ascii4(struct smbsrv_request *req, const char **dest, const uint
|
||||
|
||||
return false if any part is outside the data portion of the packet
|
||||
*/
|
||||
bool req_pull_blob(struct smbsrv_request *req, const uint8_t *src, int len, DATA_BLOB *blob)
|
||||
bool req_pull_blob(struct request_bufinfo *bufinfo, const uint8_t *src, int len, DATA_BLOB *blob)
|
||||
{
|
||||
if (len != 0 && req_data_oob(req, src, len)) {
|
||||
if (len != 0 && req_data_oob(bufinfo, src, len)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
(*blob) = data_blob_talloc(req, src, len);
|
||||
(*blob) = data_blob_talloc(bufinfo->mem_ctx, src, len);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* check that a lump of data in a request is within the bounds of the data section of
|
||||
the packet */
|
||||
bool req_data_oob(struct smbsrv_request *req, const uint8_t *ptr, uint32_t count)
|
||||
bool req_data_oob(struct request_bufinfo *bufinfo, const uint8_t *ptr, uint32_t count)
|
||||
{
|
||||
if (count == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* be careful with wraparound! */
|
||||
if (ptr < req->in.data ||
|
||||
ptr >= req->in.data + req->in.data_size ||
|
||||
count > req->in.data_size ||
|
||||
ptr + count > req->in.data + req->in.data_size) {
|
||||
if (ptr < bufinfo->data ||
|
||||
ptr >= bufinfo->data + bufinfo->data_size ||
|
||||
count > bufinfo->data_size ||
|
||||
ptr + count > bufinfo->data + bufinfo->data_size) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -129,14 +129,14 @@ void smbsrv_reply_search(struct smbsrv_request *req)
|
||||
SMBSRV_TALLOC_IO_PTR(sf, union smb_search_first);
|
||||
|
||||
p = req->in.data;
|
||||
p += req_pull_ascii4(req, &sf->search_first.in.pattern,
|
||||
p += req_pull_ascii4(&req->in.bufinfo, &sf->search_first.in.pattern,
|
||||
p, STR_TERMINATE);
|
||||
if (!sf->search_first.in.pattern) {
|
||||
smbsrv_send_error(req, NT_STATUS_OBJECT_NAME_NOT_FOUND);
|
||||
return;
|
||||
}
|
||||
|
||||
if (req_data_oob(req, p, 3)) {
|
||||
if (req_data_oob(&req->in.bufinfo, p, 3)) {
|
||||
smbsrv_send_error(req, NT_STATUS_INVALID_PARAMETER);
|
||||
return;
|
||||
}
|
||||
@ -167,7 +167,7 @@ void smbsrv_reply_search(struct smbsrv_request *req)
|
||||
union smb_search_next *sn;
|
||||
|
||||
if (resume_key_length != 21 ||
|
||||
req_data_oob(req, p, 21) ||
|
||||
req_data_oob(&req->in.bufinfo, p, 21) ||
|
||||
level == RAW_SEARCH_FUNIQUE) {
|
||||
smbsrv_send_error(req, NT_STATUS_INVALID_PARAMETER);
|
||||
return;
|
||||
@ -242,13 +242,13 @@ void smbsrv_reply_fclose(struct smbsrv_request *req)
|
||||
SMBSRV_SETUP_NTVFS_REQUEST(reply_fclose_send, NTVFS_ASYNC_STATE_MAY_ASYNC);
|
||||
|
||||
p = req->in.data;
|
||||
p += req_pull_ascii4(req, &pattern, p, STR_TERMINATE);
|
||||
p += req_pull_ascii4(&req->in.bufinfo, &pattern, p, STR_TERMINATE);
|
||||
if (pattern && *pattern) {
|
||||
smbsrv_send_error(req, NT_STATUS_INVALID_PARAMETER);
|
||||
return;
|
||||
}
|
||||
|
||||
if (req_data_oob(req, p, 3)) {
|
||||
if (req_data_oob(&req->in.bufinfo, p, 3)) {
|
||||
smbsrv_send_error(req, NT_STATUS_INVALID_PARAMETER);
|
||||
return;
|
||||
}
|
||||
@ -264,7 +264,7 @@ void smbsrv_reply_fclose(struct smbsrv_request *req)
|
||||
return;
|
||||
}
|
||||
|
||||
if (req_data_oob(req, p, 21)) {
|
||||
if (req_data_oob(&req->in.bufinfo, p, 21)) {
|
||||
smbsrv_send_error(req, NT_STATUS_INVALID_PARAMETER);
|
||||
return;
|
||||
}
|
||||
|
@ -248,7 +248,7 @@ static NTSTATUS trans2_open(struct smbsrv_request *req, struct trans_op *op)
|
||||
io->t2open.in.num_eas = 0;
|
||||
io->t2open.in.eas = NULL;
|
||||
|
||||
smbsrv_blob_pull_string(req, &trans->in.params, 28, &io->t2open.in.fname, 0);
|
||||
smbsrv_blob_pull_string(&req->in.bufinfo, &trans->in.params, 28, &io->t2open.in.fname, 0);
|
||||
if (io->t2open.in.fname == NULL) {
|
||||
return NT_STATUS_FOOBAR;
|
||||
}
|
||||
@ -296,7 +296,7 @@ static NTSTATUS trans2_mkdir(struct smbsrv_request *req, struct trans_op *op)
|
||||
NT_STATUS_HAVE_NO_MEMORY(io);
|
||||
|
||||
io->t2mkdir.level = RAW_MKDIR_T2MKDIR;
|
||||
smbsrv_blob_pull_string(req, &trans->in.params, 4, &io->t2mkdir.in.path, 0);
|
||||
smbsrv_blob_pull_string(&req->in.bufinfo, &trans->in.params, 4, &io->t2mkdir.in.path, 0);
|
||||
if (io->t2mkdir.in.path == NULL) {
|
||||
return NT_STATUS_FOOBAR;
|
||||
}
|
||||
@ -461,7 +461,7 @@ static NTSTATUS trans2_qpathinfo(struct smbsrv_request *req, struct trans_op *op
|
||||
|
||||
level = SVAL(trans->in.params.data, 0);
|
||||
|
||||
smbsrv_blob_pull_string(req, &trans->in.params, 6, &st->generic.in.file.path, 0);
|
||||
smbsrv_blob_pull_string(&req->in.bufinfo, &trans->in.params, 6, &st->generic.in.file.path, 0);
|
||||
if (st->generic.in.file.path == NULL) {
|
||||
return NT_STATUS_FOOBAR;
|
||||
}
|
||||
@ -602,7 +602,7 @@ static NTSTATUS trans2_parse_sfileinfo(struct smbsrv_request *req,
|
||||
|
||||
return smbsrv_pull_passthru_sfileinfo(st, passthru_level, st,
|
||||
blob, SMBSRV_REQ_DEFAULT_STR_FLAGS(req),
|
||||
req);
|
||||
&req->in.bufinfo);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -661,7 +661,7 @@ static NTSTATUS trans2_setpathinfo(struct smbsrv_request *req, struct trans_op *
|
||||
|
||||
level = SVAL(trans->in.params.data, 0);
|
||||
|
||||
smbsrv_blob_pull_string(req, &trans->in.params, 6, &st->generic.in.file.path, 0);
|
||||
smbsrv_blob_pull_string(&req->in.bufinfo, &trans->in.params, 6, &st->generic.in.file.path, 0);
|
||||
if (st->generic.in.file.path == NULL) {
|
||||
return NT_STATUS_FOOBAR;
|
||||
}
|
||||
@ -859,7 +859,7 @@ static NTSTATUS trans2_findfirst(struct smbsrv_request *req, struct trans_op *op
|
||||
level = SVAL(trans->in.params.data, 6);
|
||||
search->t2ffirst.in.storage_type = IVAL(trans->in.params.data, 8);
|
||||
|
||||
smbsrv_blob_pull_string(req, &trans->in.params, 12, &search->t2ffirst.in.pattern, 0);
|
||||
smbsrv_blob_pull_string(&req->in.bufinfo, &trans->in.params, 12, &search->t2ffirst.in.pattern, 0);
|
||||
if (search->t2ffirst.in.pattern == NULL) {
|
||||
return NT_STATUS_FOOBAR;
|
||||
}
|
||||
@ -945,7 +945,7 @@ static NTSTATUS trans2_findnext(struct smbsrv_request *req, struct trans_op *op)
|
||||
search->t2fnext.in.resume_key = IVAL(trans->in.params.data, 6);
|
||||
search->t2fnext.in.flags = SVAL(trans->in.params.data, 10);
|
||||
|
||||
smbsrv_blob_pull_string(req, &trans->in.params, 12, &search->t2fnext.in.last_name, 0);
|
||||
smbsrv_blob_pull_string(&req->in.bufinfo, &trans->in.params, 12, &search->t2fnext.in.last_name, 0);
|
||||
if (search->t2fnext.in.last_name == NULL) {
|
||||
return NT_STATUS_FOOBAR;
|
||||
}
|
||||
@ -1240,11 +1240,11 @@ static void reply_trans_generic(struct smbsrv_request *req, uint8_t command)
|
||||
}
|
||||
|
||||
if (command == SMBtrans) {
|
||||
req_pull_string(req, &trans->in.trans_name, req->in.data, -1, STR_TERMINATE);
|
||||
req_pull_string(&req->in.bufinfo, &trans->in.trans_name, req->in.data, -1, STR_TERMINATE);
|
||||
}
|
||||
|
||||
if (!req_pull_blob(req, req->in.hdr + param_ofs, param_count, &trans->in.params) ||
|
||||
!req_pull_blob(req, req->in.hdr + data_ofs, data_count, &trans->in.data)) {
|
||||
if (!req_pull_blob(&req->in.bufinfo, req->in.hdr + param_ofs, param_count, &trans->in.params) ||
|
||||
!req_pull_blob(&req->in.bufinfo, req->in.hdr + data_ofs, data_count, &trans->in.data)) {
|
||||
smbsrv_send_error(req, NT_STATUS_FOOBAR);
|
||||
return;
|
||||
}
|
||||
@ -1302,8 +1302,8 @@ static void reply_transs_generic(struct smbsrv_request *req, uint8_t command)
|
||||
data_ofs = SVAL(req->in.vwv, VWV(6));
|
||||
data_disp = SVAL(req->in.vwv, VWV(7));
|
||||
|
||||
if (!req_pull_blob(req, req->in.hdr + param_ofs, param_count, ¶ms) ||
|
||||
!req_pull_blob(req, req->in.hdr + data_ofs, data_count, &data)) {
|
||||
if (!req_pull_blob(&req->in.bufinfo, req->in.hdr + param_ofs, param_count, ¶ms) ||
|
||||
!req_pull_blob(&req->in.bufinfo, req->in.hdr + data_ofs, data_count, &data)) {
|
||||
smbsrv_send_error(req, NT_STATUS_INVALID_PARAMETER);
|
||||
return;
|
||||
}
|
||||
|
@ -268,7 +268,7 @@ static NTSTATUS smb2srv_setinfo_file(struct smb2srv_setinfo_op *op, uint8_t smb2
|
||||
|
||||
status = smbsrv_pull_passthru_sfileinfo(io, io->generic.level, io,
|
||||
&op->info->in.blob,
|
||||
STR_UNICODE, NULL);
|
||||
STR_UNICODE, &op->req->in.bufinfo);
|
||||
NT_STATUS_NOT_OK_RETURN(status);
|
||||
|
||||
return ntvfs_setfileinfo(op->req->ntvfs, io);
|
||||
|
@ -238,6 +238,8 @@ void smb2srv_reply_smb_negprot(struct smbsrv_request *smb_req)
|
||||
req->in.body_size = body_fixed_size;
|
||||
req->in.dynamic = NULL;
|
||||
|
||||
smb2srv_setup_bufinfo(req);
|
||||
|
||||
SIVAL(req->in.hdr, 0, SMB2_MAGIC);
|
||||
SSVAL(req->in.hdr, SMB2_HDR_LENGTH, SMB2_HDR_BODY);
|
||||
SSVAL(req->in.hdr, SMB2_HDR_EPOCH, 0);
|
||||
|
@ -30,6 +30,22 @@
|
||||
#include "ntvfs/ntvfs.h"
|
||||
#include "param/param.h"
|
||||
|
||||
|
||||
/* fill in the bufinfo */
|
||||
void smb2srv_setup_bufinfo(struct smb2srv_request *req)
|
||||
{
|
||||
req->in.bufinfo.mem_ctx = req;
|
||||
req->in.bufinfo.unicode = true;
|
||||
req->in.bufinfo.align_base = req->in.buffer;
|
||||
if (req->in.dynamic) {
|
||||
req->in.bufinfo.data = req->in.dynamic;
|
||||
req->in.bufinfo.data_size = req->in.body_size - req->in.body_fixed;
|
||||
} else {
|
||||
req->in.bufinfo.data = NULL;
|
||||
req->in.bufinfo.data_size = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int smb2srv_request_destructor(struct smb2srv_request *req)
|
||||
{
|
||||
DLIST_REMOVE(req->smb_conn->requests2.list, req);
|
||||
@ -180,6 +196,8 @@ static void smb2srv_chain_reply(struct smb2srv_request *p_req)
|
||||
}
|
||||
}
|
||||
|
||||
smb2srv_setup_bufinfo(req);
|
||||
|
||||
if (p_req->chained_file_handle) {
|
||||
memcpy(req->_chained_file_handle,
|
||||
p_req->_chained_file_handle,
|
||||
@ -430,6 +448,8 @@ NTSTATUS smbsrv_recv_smb2_request(void *private, DATA_BLOB blob)
|
||||
}
|
||||
}
|
||||
|
||||
smb2srv_setup_bufinfo(req);
|
||||
|
||||
/*
|
||||
* TODO: - make sure the length field is 64
|
||||
* - make sure it's a request
|
||||
|
@ -55,6 +55,8 @@ static NTSTATUS smb2srv_send_oplock_break(void *p, struct ntvfs_handle *h, uint8
|
||||
|
||||
req->seqnum = UINT64_MAX;
|
||||
|
||||
smb2srv_setup_bufinfo(req);
|
||||
|
||||
SIVAL(req->in.hdr, 0, SMB2_MAGIC);
|
||||
SSVAL(req->in.hdr, SMB2_HDR_LENGTH, SMB2_HDR_BODY);
|
||||
SSVAL(req->in.hdr, SMB2_HDR_EPOCH, 0);
|
||||
|
@ -254,8 +254,8 @@ struct smbsrv_request {
|
||||
/* the sequence number for signing */
|
||||
uint64_t seq_num;
|
||||
|
||||
struct request_buffer in;
|
||||
struct request_buffer out;
|
||||
struct smb_request_buffer in;
|
||||
struct smb_request_buffer out;
|
||||
};
|
||||
|
||||
enum security_types {SEC_SHARE,SEC_USER};
|
||||
|
Reference in New Issue
Block a user