mirror of
https://github.com/samba-team/samba.git
synced 2025-02-02 09:47:23 +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 used to be commit ca6d9be6cb6a403a81b18fa6e9a6a0518d7f0f68)
This commit is contained in:
parent
4c01d70a44
commit
e870cfec9f
@ -177,9 +177,9 @@ NTSTATUS smb_raw_sesssetup_recv(struct smbcli_request *req,
|
|||||||
parms->old.out.action = SVAL(req->in.vwv, VWV(2));
|
parms->old.out.action = SVAL(req->in.vwv, VWV(2));
|
||||||
p = req->in.data;
|
p = req->in.data;
|
||||||
if (p) {
|
if (p) {
|
||||||
p += smbcli_req_pull_string(req, mem_ctx, &parms->old.out.os, 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, mem_ctx, &parms->old.out.lanman, 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, mem_ctx, &parms->old.out.domain, p, -1, STR_TERMINATE);
|
p += smbcli_req_pull_string(&req->in.bufinfo, mem_ctx, &parms->old.out.domain, p, -1, STR_TERMINATE);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -190,10 +190,10 @@ NTSTATUS smb_raw_sesssetup_recv(struct smbcli_request *req,
|
|||||||
parms->nt1.out.action = SVAL(req->in.vwv, VWV(2));
|
parms->nt1.out.action = SVAL(req->in.vwv, VWV(2));
|
||||||
p = req->in.data;
|
p = req->in.data;
|
||||||
if (p) {
|
if (p) {
|
||||||
p += smbcli_req_pull_string(req, mem_ctx, &parms->nt1.out.os, 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, mem_ctx, &parms->nt1.out.lanman, 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)) {
|
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;
|
break;
|
||||||
@ -209,11 +209,11 @@ NTSTATUS smb_raw_sesssetup_recv(struct smbcli_request *req,
|
|||||||
break;
|
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 += 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->in.bufinfo, 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->in.bufinfo, 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.workgroup, p, -1, STR_TERMINATE);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RAW_SESSSETUP_SMB2:
|
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->in.ptr = req->in.data;
|
||||||
req->flags2 = SVAL(req->in.hdr, HDR_FLG2);
|
req->flags2 = SVAL(req->in.hdr, HDR_FLG2);
|
||||||
|
|
||||||
|
smb_setup_bufinfo(req);
|
||||||
|
|
||||||
if (!(req->flags2 & FLAGS2_32_BIT_ERROR_CODES)) {
|
if (!(req->flags2 & FLAGS2_32_BIT_ERROR_CODES)) {
|
||||||
int class = CVAL(req->in.hdr,HDR_RCLS);
|
int class = CVAL(req->in.hdr,HDR_RCLS);
|
||||||
int code = SVAL(req->in.hdr,HDR_ERR);
|
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);
|
p->out.data = talloc_array(mem_ctx, uint8_t, p->out.size);
|
||||||
NT_STATUS_HAVE_NO_MEMORY(p->out.data);
|
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;
|
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;
|
p = req->in.data;
|
||||||
if (!p) break;
|
if (!p) break;
|
||||||
|
|
||||||
p += smbcli_req_pull_string(req, mem_ctx, &parms->tconx.out.dev_type,
|
p += smbcli_req_pull_string(&req->in.bufinfo, mem_ctx, &parms->tconx.out.dev_type,
|
||||||
p, -1, STR_ASCII | STR_TERMINATE);
|
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.fs_type,
|
||||||
p, -1, STR_TERMINATE);
|
p, -1, STR_TERMINATE);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -250,8 +250,8 @@ struct smbcli_request {
|
|||||||
/* the mid of this packet - used to match replies */
|
/* the mid of this packet - used to match replies */
|
||||||
uint16_t mid;
|
uint16_t mid;
|
||||||
|
|
||||||
struct request_buffer in;
|
struct smb_request_buffer in;
|
||||||
struct request_buffer out;
|
struct smb_request_buffer out;
|
||||||
|
|
||||||
/* information on what to do with a reply when it is received
|
/* information on what to do with a reply when it is received
|
||||||
asyncronously. If this is not setup when a reply is received then
|
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:
|
case RAW_OPEN_CTEMP:
|
||||||
SMBCLI_CHECK_WCT(req, 1);
|
SMBCLI_CHECK_WCT(req, 1);
|
||||||
parms->ctemp.out.file.fnum = SVAL(req->in.vwv, VWV(0));
|
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;
|
break;
|
||||||
|
|
||||||
case RAW_OPEN_SPLOPEN:
|
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));
|
parms->openxreadx.out.nread = SVAL(req->in.vwv, VWV(5));
|
||||||
if (parms->openxreadx.out.nread >
|
if (parms->openxreadx.out.nread >
|
||||||
MAX(parms->openxreadx.in.mincnt, parms->openxreadx.in.maxcnt) ||
|
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.nread,
|
||||||
parms->openxreadx.out.data)) {
|
parms->openxreadx.out.data)) {
|
||||||
req->status = NT_STATUS_BUFFER_TOO_SMALL;
|
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);
|
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);
|
return smbcli_request_destroy(req);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,14 +135,14 @@ NTSTATUS smb_raw_negotiate_recv(struct smbcli_request *req)
|
|||||||
if (req->in.data_size < 16) {
|
if (req->in.data_size < 16) {
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
transport->negotiate.server_guid = smbcli_req_pull_blob(req, transport, req->in.data, 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, transport, req->in.data + 16, req->in.data_size - 16);
|
transport->negotiate.secblob = smbcli_req_pull_blob(&req->in.bufinfo, transport, req->in.data + 16, req->in.data_size - 16);
|
||||||
} else {
|
} else {
|
||||||
if (req->in.data_size < (transport->negotiate.key_len)) {
|
if (req->in.data_size < (transport->negotiate.key_len)) {
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
transport->negotiate.secblob = smbcli_req_pull_blob(req, transport, req->in.data, transport->negotiate.key_len);
|
transport->negotiate.secblob = smbcli_req_pull_blob(&req->in.bufinfo, transport, req->in.data, transport->negotiate.key_len);
|
||||||
smbcli_req_pull_string(req, transport, &transport->negotiate.server_domain,
|
smbcli_req_pull_string(&req->in.bufinfo, transport, &transport->negotiate.server_domain,
|
||||||
req->in.data+transport->negotiate.key_len,
|
req->in.data+transport->negotiate.key_len,
|
||||||
req->in.data_size-transport->negotiate.key_len, STR_UNICODE|STR_NOALIGN);
|
req->in.data_size-transport->negotiate.key_len, STR_UNICODE|STR_NOALIGN);
|
||||||
/* here comes the server name */
|
/* 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)) {
|
if ((SVAL(req->in.vwv,VWV(5)) & 0x2)) {
|
||||||
transport->negotiate.writebraw_supported = 1;
|
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);
|
req->in.data, req->in.data_size);
|
||||||
} else {
|
} else {
|
||||||
/* the old core protocol */
|
/* 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);
|
SMBCLI_CHECK_WCT(req, 5);
|
||||||
parms->lockread.out.nread = SVAL(req->in.vwv, VWV(0));
|
parms->lockread.out.nread = SVAL(req->in.vwv, VWV(0));
|
||||||
if (parms->lockread.out.nread > parms->lockread.in.count ||
|
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)) {
|
parms->lockread.out.nread, parms->lockread.out.data)) {
|
||||||
req->status = NT_STATUS_BUFFER_TOO_SMALL;
|
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);
|
SMBCLI_CHECK_WCT(req, 5);
|
||||||
parms->read.out.nread = SVAL(req->in.vwv, VWV(0));
|
parms->read.out.nread = SVAL(req->in.vwv, VWV(0));
|
||||||
if (parms->read.out.nread > parms->read.in.count ||
|
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)) {
|
parms->read.out.nread, parms->read.out.data)) {
|
||||||
req->status = NT_STATUS_BUFFER_TOO_SMALL;
|
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) ||
|
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.nread,
|
||||||
parms->readx.out.data)) {
|
parms->readx.out.data)) {
|
||||||
req->status = NT_STATUS_BUFFER_TOO_SMALL;
|
req->status = NT_STATUS_BUFFER_TOO_SMALL;
|
||||||
|
@ -34,6 +34,17 @@
|
|||||||
/* assume that a character will not consume more than 3 bytes per char */
|
/* assume that a character will not consume more than 3 bytes per char */
|
||||||
#define MAX_BYTES_PER_CHAR 3
|
#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 */
|
/* destroy a request structure and return final status */
|
||||||
NTSTATUS smbcli_request_destroy(struct smbcli_request *req)
|
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 = req->in.vwv + 2 + req->in.wct * 2;
|
||||||
req->in.data_size = SVAL(req->in.vwv, VWV(req->in.wct));
|
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 >
|
if (buffer + 3 + req->in.wct*2 + req->in.data_size >
|
||||||
req->in.buffer + req->in.size) {
|
req->in.buffer + req->in.size) {
|
||||||
return NT_STATUS_BUFFER_TOO_SMALL;
|
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
|
on failure zero is returned and *dest is set to NULL, otherwise the number
|
||||||
of bytes consumed in the packet is returned
|
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)
|
char **dest, const uint8_t *src, int byte_len, uint_t flags)
|
||||||
{
|
{
|
||||||
int src_len, src_len2, alignment=0;
|
int src_len, src_len2, alignment=0;
|
||||||
ssize_t ret;
|
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++;
|
src++;
|
||||||
alignment=1;
|
alignment=1;
|
||||||
if (byte_len != -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) {
|
if (src_len < 0) {
|
||||||
*dest = NULL;
|
*dest = NULL;
|
||||||
return 0;
|
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
|
on failure zero is returned and *dest is set to NULL, otherwise the number
|
||||||
of bytes consumed in the packet is returned
|
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)
|
char **dest, const uint8_t *src, int byte_len, uint_t flags)
|
||||||
{
|
{
|
||||||
int src_len, src_len2;
|
int src_len, src_len2;
|
||||||
ssize_t ret;
|
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) {
|
if (src_len < 0) {
|
||||||
*dest = NULL;
|
*dest = NULL;
|
||||||
return 0;
|
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
|
on failure zero is returned and *dest is set to NULL, otherwise the number
|
||||||
of bytes consumed in the packet is returned
|
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)
|
char **dest, const uint8_t *src, int byte_len, uint_t flags)
|
||||||
{
|
{
|
||||||
if (!(flags & STR_ASCII) &&
|
if (!(flags & STR_ASCII) &&
|
||||||
(((flags & STR_UNICODE) || (req->flags2 & FLAGS2_UNICODE_STRINGS)))) {
|
(((flags & STR_UNICODE) || bufinfo->unicode))) {
|
||||||
return smbcli_req_pull_ucs2(req, mem_ctx, dest, src, byte_len, flags);
|
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
|
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;
|
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) {
|
if (src_len < 0) {
|
||||||
return data_blob(NULL, 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
|
/* check that a lump of data in a request is within the bounds of the data section of
|
||||||
the packet */
|
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! */
|
/* be careful with wraparound! */
|
||||||
if (ptr < req->in.data ||
|
if (ptr < bufinfo->data ||
|
||||||
ptr >= req->in.data + req->in.data_size ||
|
ptr >= bufinfo->data + bufinfo->data_size ||
|
||||||
count > req->in.data_size ||
|
count > bufinfo->data_size ||
|
||||||
ptr + count > req->in.data + req->in.data_size) {
|
ptr + count > bufinfo->data + bufinfo->data_size) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
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
|
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 (len == 0) return true;
|
||||||
|
|
||||||
if (smbcli_req_data_oob(req, src, len)) {
|
if (smbcli_req_data_oob(bufinfo, src, len)) {
|
||||||
return false;
|
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,
|
search_data.search.write_time = raw_pull_dos_date(req->transport,
|
||||||
p + 22);
|
p + 22);
|
||||||
search_data.search.size = IVAL(p, 26);
|
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;
|
search_data.search.name = name;
|
||||||
if (!callback(private, &search_data)) {
|
if (!callback(private, &search_data)) {
|
||||||
break;
|
break;
|
||||||
|
@ -22,11 +22,22 @@
|
|||||||
|
|
||||||
#include "libcli/raw/signing.h"
|
#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.
|
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 */
|
/* the raw SMB buffer, including the 4 byte length header */
|
||||||
uint8_t *buffer;
|
uint8_t *buffer;
|
||||||
|
|
||||||
@ -56,6 +67,9 @@ struct request_buffer {
|
|||||||
* a send packet is done we need to move this
|
* a send packet is done we need to move this
|
||||||
* pointer */
|
* pointer */
|
||||||
uint8_t *ptr;
|
uint8_t *ptr;
|
||||||
|
|
||||||
|
/* this is used to range check and align strings and buffers */
|
||||||
|
struct request_bufinfo bufinfo;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -65,7 +65,7 @@ static bool smbcli_set_smb_signing_common(struct smbcli_transport *transport)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void mark_packet_signed(struct request_buffer *out)
|
void mark_packet_signed(struct smb_request_buffer *out)
|
||||||
{
|
{
|
||||||
uint16_t flags2;
|
uint16_t flags2;
|
||||||
flags2 = SVAL(out->hdr, HDR_FLG2);
|
flags2 = SVAL(out->hdr, HDR_FLG2);
|
||||||
@ -101,7 +101,7 @@ bool signing_good(struct smb_signing_context *sign_info,
|
|||||||
return true;
|
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];
|
uint8_t calc_md5_mac[16];
|
||||||
struct MD5Context md5_ctx;
|
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...*/
|
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;
|
bool good;
|
||||||
uint8_t calc_md5_mac[16];
|
uint8_t calc_md5_mac[16];
|
||||||
|
@ -28,6 +28,21 @@
|
|||||||
#include "libcli/smb2/smb2_calls.h"
|
#include "libcli/smb2/smb2_calls.h"
|
||||||
#include "param/param.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
|
initialise a smb2 request
|
||||||
*/
|
*/
|
||||||
|
@ -19,6 +19,8 @@
|
|||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "libcli/raw/request.h"
|
||||||
|
|
||||||
struct smb2_options {
|
struct smb2_options {
|
||||||
uint32_t timeout;
|
uint32_t timeout;
|
||||||
};
|
};
|
||||||
@ -102,6 +104,9 @@ struct smb2_request_buffer {
|
|||||||
* this will be moved when some dynamic data is pushed
|
* this will be moved when some dynamic data is pushed
|
||||||
*/
|
*/
|
||||||
uint8_t *dynamic;
|
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));
|
DEBUG(2, ("SMB2 RECV seqnum=0x%llx\n", (long long)req->seqnum));
|
||||||
dump_data(5, req->in.body, req->in.body_size);
|
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
|
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,
|
const DATA_BLOB *blob,
|
||||||
uint16_t offset,
|
uint16_t offset,
|
||||||
const char **str,
|
const char **str,
|
||||||
@ -92,7 +92,7 @@ size_t smbsrv_blob_pull_string(struct smbsrv_request *req,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return req_pull_string(req, str,
|
return req_pull_string(bufinfo, str,
|
||||||
blob->data + offset,
|
blob->data + offset,
|
||||||
blob->length - offset,
|
blob->length - offset,
|
||||||
STR_NO_RANGE_CHECK | flags);
|
STR_NO_RANGE_CHECK | flags);
|
||||||
@ -521,7 +521,7 @@ NTSTATUS smbsrv_pull_passthru_sfileinfo(TALLOC_CTX *mem_ctx,
|
|||||||
union smb_setfileinfo *st,
|
union smb_setfileinfo *st,
|
||||||
const DATA_BLOB *blob,
|
const DATA_BLOB *blob,
|
||||||
int default_str_flags,
|
int default_str_flags,
|
||||||
struct smbsrv_request *req)
|
struct request_bufinfo *bufinfo)
|
||||||
{
|
{
|
||||||
uint32_t len;
|
uint32_t len;
|
||||||
DATA_BLOB str_blob;
|
DATA_BLOB str_blob;
|
||||||
@ -560,12 +560,8 @@ NTSTATUS smbsrv_pull_passthru_sfileinfo(TALLOC_CTX *mem_ctx,
|
|||||||
return NT_STATUS_OK;
|
return NT_STATUS_OK;
|
||||||
|
|
||||||
case RAW_SFILEINFO_RENAME_INFORMATION:
|
case RAW_SFILEINFO_RENAME_INFORMATION:
|
||||||
if (!req) {
|
if (!bufinfo) {
|
||||||
/*
|
return NT_STATUS_INTERNAL_ERROR;
|
||||||
* TODO: get rid of smbsrv_request argument of
|
|
||||||
* smbsrv_blob_pull_string()
|
|
||||||
*/
|
|
||||||
return NT_STATUS_NOT_IMPLEMENTED;
|
|
||||||
}
|
}
|
||||||
BLOB_CHECK_MIN_SIZE(blob, 12);
|
BLOB_CHECK_MIN_SIZE(blob, 12);
|
||||||
|
|
||||||
@ -574,7 +570,7 @@ NTSTATUS smbsrv_pull_passthru_sfileinfo(TALLOC_CTX *mem_ctx,
|
|||||||
len = IVAL(blob->data, 8);
|
len = IVAL(blob->data, 8);
|
||||||
str_blob.data = blob->data+12;
|
str_blob.data = blob->data+12;
|
||||||
str_blob.length = MIN(blob->length, len);
|
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,
|
&st->rename_information.in.new_name,
|
||||||
STR_UNICODE);
|
STR_UNICODE);
|
||||||
if (st->rename_information.in.new_name == NULL) {
|
if (st->rename_information.in.new_name == NULL) {
|
||||||
|
@ -509,7 +509,7 @@ void smbsrv_reply_negprot(struct smbsrv_request *req)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
protos[protos_count] = NULL;
|
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;
|
p += len;
|
||||||
if (len == 0 || !protos[protos_count]) break;
|
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.sec_desc = NULL;
|
||||||
io->ntcreatex.in.ea_list = 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,
|
params + 53,
|
||||||
MIN(fname_len+1, trans->in.params.length - 53),
|
MIN(fname_len+1, trans->in.params.length - 53),
|
||||||
STR_NO_RANGE_CHECK | STR_TERMINATE);
|
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),
|
memcpy(trans->in.setup, (char *)(req->in.vwv) + VWV(19),
|
||||||
sizeof(uint16_t) * trans->in.setup_count);
|
sizeof(uint16_t) * trans->in.setup_count);
|
||||||
|
|
||||||
if (!req_pull_blob(req, req->in.hdr + param_ofs, param_count, &trans->in.params) ||
|
if (!req_pull_blob(&req->in.bufinfo, req->in.hdr + param_ofs, param_count, &trans->in.params) ||
|
||||||
!req_pull_blob(req, req->in.hdr + data_ofs, data_count, &trans->in.data)) {
|
!req_pull_blob(&req->in.bufinfo, req->in.hdr + data_ofs, data_count, &trans->in.data)) {
|
||||||
smbsrv_send_error(req, NT_STATUS_FOOBAR);
|
smbsrv_send_error(req, NT_STATUS_FOOBAR);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -151,6 +151,9 @@ NTSTATUS smbsrv_recv_smb_request(void *private, DATA_BLOB blob)
|
|||||||
|
|
||||||
req->flags2 = SVAL(req->in.hdr, HDR_FLG2);
|
req->flags2 = SVAL(req->in.hdr, HDR_FLG2);
|
||||||
|
|
||||||
|
/* fix the bufinfo */
|
||||||
|
smbsrv_setup_bufinfo(req);
|
||||||
|
|
||||||
if (!smbsrv_signing_check_incoming(req)) {
|
if (!smbsrv_signing_check_incoming(req)) {
|
||||||
smbsrv_send_error(req, NT_STATUS_ACCESS_DENIED);
|
smbsrv_send_error(req, NT_STATUS_ACCESS_DENIED);
|
||||||
return NT_STATUS_OK;
|
return NT_STATUS_OK;
|
||||||
@ -620,6 +623,9 @@ void smbsrv_chain_reply(struct smbsrv_request *req)
|
|||||||
req->in.data_size = data_size;
|
req->in.data_size = data_size;
|
||||||
req->in.ptr = data;
|
req->in.ptr = data;
|
||||||
|
|
||||||
|
/* fix the bufinfo */
|
||||||
|
smbsrv_setup_bufinfo(req);
|
||||||
|
|
||||||
req->chain_count++;
|
req->chain_count++;
|
||||||
|
|
||||||
SSVAL(req->out.vwv, VWV(0), chain_cmd);
|
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;
|
con.tcon.level = RAW_TCON_TCON;
|
||||||
|
|
||||||
p = req->in.data;
|
p = req->in.data;
|
||||||
p += req_pull_ascii4(req, &con.tcon.in.service, p, STR_TERMINATE);
|
p += req_pull_ascii4(&req->in.bufinfo, &con.tcon.in.service, p, STR_TERMINATE);
|
||||||
p += req_pull_ascii4(req, &con.tcon.in.password, p, STR_TERMINATE);
|
p += req_pull_ascii4(&req->in.bufinfo, &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.dev, p, STR_TERMINATE);
|
||||||
|
|
||||||
if (!con.tcon.in.service || !con.tcon.in.password || !con.tcon.in.dev) {
|
if (!con.tcon.in.service || !con.tcon.in.password || !con.tcon.in.dev) {
|
||||||
smbsrv_send_error(req, NT_STATUS_INVALID_PARAMETER);
|
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;
|
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);
|
smbsrv_send_error(req, NT_STATUS_ILL_FORMED_PASSWORD);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
p += passlen;
|
p += passlen;
|
||||||
|
|
||||||
p += req_pull_string(req, &con.tconx.in.path, p, -1, STR_TERMINATE);
|
p += req_pull_string(&req->in.bufinfo, &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.device, p, -1, STR_ASCII);
|
||||||
|
|
||||||
if (!con.tconx.in.path || !con.tconx.in.device) {
|
if (!con.tconx.in.path || !con.tconx.in.device) {
|
||||||
smbsrv_send_error(req, NT_STATUS_BAD_DEVICE_TYPE);
|
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_TALLOC_IO_PTR(io, union smb_chkpath);
|
||||||
SMBSRV_SETUP_NTVFS_REQUEST(reply_simple_send, NTVFS_ASYNC_STATE_MAY_ASYNC);
|
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));
|
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;
|
st->getattr.level = RAW_FILEINFO_GETATTR;
|
||||||
|
|
||||||
/* parse request */
|
/* 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) {
|
if (!st->getattr.in.file.path) {
|
||||||
smbsrv_send_error(req, NT_STATUS_OBJECT_NAME_NOT_FOUND);
|
smbsrv_send_error(req, NT_STATUS_OBJECT_NAME_NOT_FOUND);
|
||||||
return;
|
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.attrib = SVAL(req->in.vwv, VWV(0));
|
||||||
st->setattr.in.write_time = srv_pull_dos_date3(req->smb_conn, req->in.vwv + VWV(1));
|
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) {
|
if (!st->setattr.in.file.path) {
|
||||||
smbsrv_send_error(req, NT_STATUS_OBJECT_NAME_NOT_FOUND);
|
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.open_mode = SVAL(req->in.vwv, VWV(0));
|
||||||
oi->openold.in.search_attrs = SVAL(req->in.vwv, VWV(1));
|
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) {
|
if (!oi->openold.in.fname) {
|
||||||
smbsrv_send_error(req, NT_STATUS_OBJECT_NAME_NOT_FOUND);
|
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.size = IVAL(req->in.vwv, VWV(9));
|
||||||
oi->openx.in.timeout = IVAL(req->in.vwv, VWV(11));
|
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) {
|
if (!oi->openx.in.fname) {
|
||||||
smbsrv_send_error(req, NT_STATUS_OBJECT_NAME_NOT_FOUND);
|
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.attrib = SVAL(req->in.vwv, VWV(0));
|
||||||
oi->mknew.in.write_time = srv_pull_dos_date3(req->smb_conn, req->in.vwv + VWV(1));
|
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) {
|
if (!oi->mknew.in.fname) {
|
||||||
smbsrv_send_error(req, NT_STATUS_OBJECT_NAME_NOT_FOUND);
|
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
|
/* the filename is actually a directory name, the server provides a filename
|
||||||
in that directory */
|
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) {
|
if (!oi->ctemp.in.directory) {
|
||||||
smbsrv_send_error(req, NT_STATUS_OBJECT_NAME_NOT_FOUND);
|
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));
|
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));
|
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;
|
io->write.in.data = req->in.data + 3;
|
||||||
|
|
||||||
/* make sure they gave us the data they promised */
|
/* 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);
|
smbsrv_send_error(req, NT_STATUS_FOOBAR);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1027,7 +1027,7 @@ void smbsrv_reply_write_and_X(struct smbsrv_request *req)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* make sure the data is in bounds */
|
/* 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);
|
smbsrv_send_error(req, NT_STATUS_FOOBAR);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1163,7 +1163,7 @@ void smbsrv_reply_writeclose(struct smbsrv_request *req)
|
|||||||
io->writeclose.in.data = req->in.data + 1;
|
io->writeclose.in.data = req->in.data + 1;
|
||||||
|
|
||||||
/* make sure they gave us the data they promised */
|
/* 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);
|
smbsrv_send_error(req, NT_STATUS_FOOBAR);
|
||||||
return;
|
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.setup_length = SVAL(req->in.vwv, VWV(0));
|
||||||
oi->splopen.in.mode = SVAL(req->in.vwv, VWV(1));
|
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));
|
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;
|
io->splwrite.in.data = req->in.data + 3;
|
||||||
|
|
||||||
/* make sure they gave us the data they promised */
|
/* 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);
|
smbsrv_send_error(req, NT_STATUS_FOOBAR);
|
||||||
return;
|
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);
|
SMBSRV_SETUP_NTVFS_REQUEST(reply_simple_send, NTVFS_ASYNC_STATE_MAY_ASYNC);
|
||||||
|
|
||||||
io->generic.level = RAW_MKDIR_MKDIR;
|
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));
|
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_TALLOC_IO_PTR(io, struct smb_rmdir);
|
||||||
SMBSRV_SETUP_NTVFS_REQUEST(reply_simple_send, NTVFS_ASYNC_STATE_MAY_ASYNC);
|
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));
|
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));
|
io->rename.in.attrib = SVAL(req->in.vwv, VWV(0));
|
||||||
|
|
||||||
p = req->in.data;
|
p = req->in.data;
|
||||||
p += req_pull_ascii4(req, &io->rename.in.pattern1, p, STR_TERMINATE);
|
p += req_pull_ascii4(&req->in.bufinfo, &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.pattern2, p, STR_TERMINATE);
|
||||||
|
|
||||||
if (!io->rename.in.pattern1 || !io->rename.in.pattern2) {
|
if (!io->rename.in.pattern1 || !io->rename.in.pattern2) {
|
||||||
smbsrv_send_error(req, NT_STATUS_FOOBAR);
|
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));
|
io->ntrename.in.cluster_size = IVAL(req->in.vwv, VWV(2));
|
||||||
|
|
||||||
p = req->in.data;
|
p = req->in.data;
|
||||||
p += req_pull_ascii4(req, &io->ntrename.in.old_name, p, STR_TERMINATE);
|
p += req_pull_ascii4(&req->in.bufinfo, &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.new_name, p, STR_TERMINATE);
|
||||||
|
|
||||||
if (!io->ntrename.in.old_name || !io->ntrename.in.new_name) {
|
if (!io->ntrename.in.old_name || !io->ntrename.in.new_name) {
|
||||||
smbsrv_send_error(req, NT_STATUS_FOOBAR);
|
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));
|
cp->in.flags = SVAL(req->in.vwv, VWV(2));
|
||||||
|
|
||||||
p = req->in.data;
|
p = req->in.data;
|
||||||
p += req_pull_ascii4(req, &cp->in.path1, p, STR_TERMINATE);
|
p += req_pull_ascii4(&req->in.bufinfo, &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.path2, p, STR_TERMINATE);
|
||||||
|
|
||||||
if (!cp->in.path1 || !cp->in.path2) {
|
if (!cp->in.path1 || !cp->in.path2) {
|
||||||
smbsrv_send_error(req, NT_STATUS_FOOBAR);
|
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 */
|
/* 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);
|
smbsrv_send_error(req, NT_STATUS_FOOBAR);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1877,22 +1877,22 @@ static void reply_sesssetup_old(struct smbsrv_request *req)
|
|||||||
passlen = SVAL(req->in.vwv, VWV(7));
|
passlen = SVAL(req->in.vwv, VWV(7));
|
||||||
|
|
||||||
/* check the request isn't malformed */
|
/* 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);
|
smbsrv_send_error(req, NT_STATUS_FOOBAR);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
p = req->in.data;
|
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);
|
smbsrv_send_error(req, NT_STATUS_FOOBAR);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
p += passlen;
|
p += passlen;
|
||||||
|
|
||||||
p += req_pull_string(req, &io->old.in.user, p, -1, STR_TERMINATE);
|
p += req_pull_string(&req->in.bufinfo, &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->in.bufinfo, &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->in.bufinfo, &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.lanman, p, -1, STR_TERMINATE);
|
||||||
|
|
||||||
/* call the generic handler */
|
/* call the generic handler */
|
||||||
smbsrv_sesssetup_backend(req, io);
|
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));
|
io->nt1.in.capabilities = IVAL(req->in.vwv, VWV(11));
|
||||||
|
|
||||||
/* check the request isn't malformed */
|
/* check the request isn't malformed */
|
||||||
if (req_data_oob(req, req->in.data, passlen1) ||
|
if (req_data_oob(&req->in.bufinfo, req->in.data, passlen1) ||
|
||||||
req_data_oob(req, req->in.data + passlen1, passlen2)) {
|
req_data_oob(&req->in.bufinfo, req->in.data + passlen1, passlen2)) {
|
||||||
smbsrv_send_error(req, NT_STATUS_FOOBAR);
|
smbsrv_send_error(req, NT_STATUS_FOOBAR);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
p = req->in.data;
|
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);
|
smbsrv_send_error(req, NT_STATUS_FOOBAR);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
p += passlen1;
|
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);
|
smbsrv_send_error(req, NT_STATUS_FOOBAR);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
p += passlen2;
|
p += passlen2;
|
||||||
|
|
||||||
p += req_pull_string(req, &io->nt1.in.user, p, -1, STR_TERMINATE);
|
p += req_pull_string(&req->in.bufinfo, &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->in.bufinfo, &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->in.bufinfo, &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.lanman, p, -1, STR_TERMINATE);
|
||||||
|
|
||||||
/* call the generic handler */
|
/* call the generic handler */
|
||||||
smbsrv_sesssetup_backend(req, io);
|
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));
|
io->spnego.in.capabilities = IVAL(req->in.vwv, VWV(10));
|
||||||
|
|
||||||
p = req->in.data;
|
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);
|
smbsrv_send_error(req, NT_STATUS_FOOBAR);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
p += blob_len;
|
p += blob_len;
|
||||||
|
|
||||||
p += req_pull_string(req, &io->spnego.in.os, p, -1, STR_TERMINATE);
|
p += req_pull_string(&req->in.bufinfo, &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->in.bufinfo, &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.workgroup, p, -1, STR_TERMINATE);
|
||||||
|
|
||||||
/* call the generic handler */
|
/* call the generic handler */
|
||||||
smbsrv_sesssetup_backend(req, io);
|
smbsrv_sesssetup_backend(req, io);
|
||||||
@ -2199,7 +2199,7 @@ void smbsrv_reply_ntcreate_and_X(struct smbsrv_request *req)
|
|||||||
fname_len++;
|
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) {
|
if (!io->ntcreatex.in.fname) {
|
||||||
smbsrv_send_error(req, NT_STATUS_FOOBAR);
|
smbsrv_send_error(req, NT_STATUS_FOOBAR);
|
||||||
return;
|
return;
|
||||||
|
@ -33,6 +33,17 @@
|
|||||||
/* we over allocate the data buffer to prevent too many realloc calls */
|
/* we over allocate the data buffer to prevent too many realloc calls */
|
||||||
#define REQ_OVER_ALLOCATION 0
|
#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)
|
static int smbsrv_request_destructor(struct smbsrv_request *req)
|
||||||
{
|
{
|
||||||
DLIST_REMOVE(req->smb_conn->requests, 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
|
on failure zero is returned and *dest is set to NULL, otherwise the number
|
||||||
of bytes consumed in the packet is returned
|
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;
|
int src_len, src_len2, alignment=0;
|
||||||
ssize_t ret;
|
ssize_t ret;
|
||||||
char *dest2;
|
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++;
|
src++;
|
||||||
alignment=1;
|
alignment=1;
|
||||||
if (byte_len != -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) {
|
if (flags & STR_NO_RANGE_CHECK) {
|
||||||
src_len = byte_len;
|
src_len = byte_len;
|
||||||
} else {
|
} 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) {
|
if (byte_len != -1 && src_len > byte_len) {
|
||||||
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);
|
src_len2 = utf16_len_n(src, src_len);
|
||||||
if (src_len2 == 0) {
|
if (src_len2 == 0) {
|
||||||
*dest = talloc_strdup(req, "");
|
*dest = talloc_strdup(bufinfo->mem_ctx, "");
|
||||||
return src_len2 + alignment;
|
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) {
|
if (ret == -1) {
|
||||||
*dest = NULL;
|
*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
|
on failure zero is returned and *dest is set to NULL, otherwise the number
|
||||||
of bytes consumed in the packet is returned
|
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;
|
int src_len, src_len2;
|
||||||
ssize_t ret;
|
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) {
|
if (flags & STR_NO_RANGE_CHECK) {
|
||||||
src_len = byte_len;
|
src_len = byte_len;
|
||||||
} else {
|
} 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) {
|
if (src_len < 0) {
|
||||||
*dest = NULL;
|
*dest = NULL;
|
||||||
return 0;
|
return 0;
|
||||||
@ -544,7 +555,7 @@ static size_t req_pull_ascii(struct smbsrv_request *req, const char **dest, cons
|
|||||||
src_len2++;
|
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) {
|
if (ret == -1) {
|
||||||
*dest = NULL;
|
*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
|
on failure zero is returned and *dest is set to NULL, otherwise the number
|
||||||
of bytes consumed in the packet is returned
|
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) &&
|
if (!(flags & STR_ASCII) &&
|
||||||
(((flags & STR_UNICODE) || (req->flags2 & FLAGS2_UNICODE_STRINGS)))) {
|
(((flags & STR_UNICODE) || bufinfo->unicode))) {
|
||||||
return req_pull_ucs2(req, dest, src, byte_len, flags);
|
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
|
on failure *dest is set to the zero length string. This seems to
|
||||||
match win2000 behaviour
|
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;
|
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! */
|
/* win2000 treats this as the empty string! */
|
||||||
(*dest) = talloc_strdup(req, "");
|
(*dest) = talloc_strdup(bufinfo->mem_ctx, "");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -603,9 +614,9 @@ size_t req_pull_ascii4(struct smbsrv_request *req, const char **dest, const uint
|
|||||||
behaviour */
|
behaviour */
|
||||||
src++;
|
src++;
|
||||||
|
|
||||||
ret = req_pull_string(req, dest, src, -1, flags);
|
ret = req_pull_string(bufinfo, dest, src, -1, flags);
|
||||||
if (ret == -1) {
|
if (ret == -1) {
|
||||||
(*dest) = talloc_strdup(req, "");
|
(*dest) = talloc_strdup(bufinfo->mem_ctx, "");
|
||||||
return 1;
|
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
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
(*blob) = data_blob_talloc(req, src, len);
|
(*blob) = data_blob_talloc(bufinfo->mem_ctx, src, len);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check that a lump of data in a request is within the bounds of the data section of
|
/* check that a lump of data in a request is within the bounds of the data section of
|
||||||
the packet */
|
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) {
|
if (count == 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* be careful with wraparound! */
|
/* be careful with wraparound! */
|
||||||
if (ptr < req->in.data ||
|
if (ptr < bufinfo->data ||
|
||||||
ptr >= req->in.data + req->in.data_size ||
|
ptr >= bufinfo->data + bufinfo->data_size ||
|
||||||
count > req->in.data_size ||
|
count > bufinfo->data_size ||
|
||||||
ptr + count > req->in.data + req->in.data_size) {
|
ptr + count > bufinfo->data + bufinfo->data_size) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -129,14 +129,14 @@ void smbsrv_reply_search(struct smbsrv_request *req)
|
|||||||
SMBSRV_TALLOC_IO_PTR(sf, union smb_search_first);
|
SMBSRV_TALLOC_IO_PTR(sf, union smb_search_first);
|
||||||
|
|
||||||
p = req->in.data;
|
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);
|
p, STR_TERMINATE);
|
||||||
if (!sf->search_first.in.pattern) {
|
if (!sf->search_first.in.pattern) {
|
||||||
smbsrv_send_error(req, NT_STATUS_OBJECT_NAME_NOT_FOUND);
|
smbsrv_send_error(req, NT_STATUS_OBJECT_NAME_NOT_FOUND);
|
||||||
return;
|
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);
|
smbsrv_send_error(req, NT_STATUS_INVALID_PARAMETER);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -167,7 +167,7 @@ void smbsrv_reply_search(struct smbsrv_request *req)
|
|||||||
union smb_search_next *sn;
|
union smb_search_next *sn;
|
||||||
|
|
||||||
if (resume_key_length != 21 ||
|
if (resume_key_length != 21 ||
|
||||||
req_data_oob(req, p, 21) ||
|
req_data_oob(&req->in.bufinfo, p, 21) ||
|
||||||
level == RAW_SEARCH_FUNIQUE) {
|
level == RAW_SEARCH_FUNIQUE) {
|
||||||
smbsrv_send_error(req, NT_STATUS_INVALID_PARAMETER);
|
smbsrv_send_error(req, NT_STATUS_INVALID_PARAMETER);
|
||||||
return;
|
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);
|
SMBSRV_SETUP_NTVFS_REQUEST(reply_fclose_send, NTVFS_ASYNC_STATE_MAY_ASYNC);
|
||||||
|
|
||||||
p = req->in.data;
|
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) {
|
if (pattern && *pattern) {
|
||||||
smbsrv_send_error(req, NT_STATUS_INVALID_PARAMETER);
|
smbsrv_send_error(req, NT_STATUS_INVALID_PARAMETER);
|
||||||
return;
|
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);
|
smbsrv_send_error(req, NT_STATUS_INVALID_PARAMETER);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -264,7 +264,7 @@ void smbsrv_reply_fclose(struct smbsrv_request *req)
|
|||||||
return;
|
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);
|
smbsrv_send_error(req, NT_STATUS_INVALID_PARAMETER);
|
||||||
return;
|
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.num_eas = 0;
|
||||||
io->t2open.in.eas = NULL;
|
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) {
|
if (io->t2open.in.fname == NULL) {
|
||||||
return NT_STATUS_FOOBAR;
|
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);
|
NT_STATUS_HAVE_NO_MEMORY(io);
|
||||||
|
|
||||||
io->t2mkdir.level = RAW_MKDIR_T2MKDIR;
|
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) {
|
if (io->t2mkdir.in.path == NULL) {
|
||||||
return NT_STATUS_FOOBAR;
|
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);
|
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) {
|
if (st->generic.in.file.path == NULL) {
|
||||||
return NT_STATUS_FOOBAR;
|
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,
|
return smbsrv_pull_passthru_sfileinfo(st, passthru_level, st,
|
||||||
blob, SMBSRV_REQ_DEFAULT_STR_FLAGS(req),
|
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);
|
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) {
|
if (st->generic.in.file.path == NULL) {
|
||||||
return NT_STATUS_FOOBAR;
|
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);
|
level = SVAL(trans->in.params.data, 6);
|
||||||
search->t2ffirst.in.storage_type = IVAL(trans->in.params.data, 8);
|
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) {
|
if (search->t2ffirst.in.pattern == NULL) {
|
||||||
return NT_STATUS_FOOBAR;
|
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.resume_key = IVAL(trans->in.params.data, 6);
|
||||||
search->t2fnext.in.flags = SVAL(trans->in.params.data, 10);
|
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) {
|
if (search->t2fnext.in.last_name == NULL) {
|
||||||
return NT_STATUS_FOOBAR;
|
return NT_STATUS_FOOBAR;
|
||||||
}
|
}
|
||||||
@ -1240,11 +1240,11 @@ static void reply_trans_generic(struct smbsrv_request *req, uint8_t command)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (command == SMBtrans) {
|
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) ||
|
if (!req_pull_blob(&req->in.bufinfo, req->in.hdr + param_ofs, param_count, &trans->in.params) ||
|
||||||
!req_pull_blob(req, req->in.hdr + data_ofs, data_count, &trans->in.data)) {
|
!req_pull_blob(&req->in.bufinfo, req->in.hdr + data_ofs, data_count, &trans->in.data)) {
|
||||||
smbsrv_send_error(req, NT_STATUS_FOOBAR);
|
smbsrv_send_error(req, NT_STATUS_FOOBAR);
|
||||||
return;
|
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_ofs = SVAL(req->in.vwv, VWV(6));
|
||||||
data_disp = SVAL(req->in.vwv, VWV(7));
|
data_disp = SVAL(req->in.vwv, VWV(7));
|
||||||
|
|
||||||
if (!req_pull_blob(req, req->in.hdr + param_ofs, param_count, ¶ms) ||
|
if (!req_pull_blob(&req->in.bufinfo, req->in.hdr + param_ofs, param_count, ¶ms) ||
|
||||||
!req_pull_blob(req, req->in.hdr + data_ofs, data_count, &data)) {
|
!req_pull_blob(&req->in.bufinfo, req->in.hdr + data_ofs, data_count, &data)) {
|
||||||
smbsrv_send_error(req, NT_STATUS_INVALID_PARAMETER);
|
smbsrv_send_error(req, NT_STATUS_INVALID_PARAMETER);
|
||||||
return;
|
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,
|
status = smbsrv_pull_passthru_sfileinfo(io, io->generic.level, io,
|
||||||
&op->info->in.blob,
|
&op->info->in.blob,
|
||||||
STR_UNICODE, NULL);
|
STR_UNICODE, &op->req->in.bufinfo);
|
||||||
NT_STATUS_NOT_OK_RETURN(status);
|
NT_STATUS_NOT_OK_RETURN(status);
|
||||||
|
|
||||||
return ntvfs_setfileinfo(op->req->ntvfs, io);
|
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.body_size = body_fixed_size;
|
||||||
req->in.dynamic = NULL;
|
req->in.dynamic = NULL;
|
||||||
|
|
||||||
|
smb2srv_setup_bufinfo(req);
|
||||||
|
|
||||||
SIVAL(req->in.hdr, 0, SMB2_MAGIC);
|
SIVAL(req->in.hdr, 0, SMB2_MAGIC);
|
||||||
SSVAL(req->in.hdr, SMB2_HDR_LENGTH, SMB2_HDR_BODY);
|
SSVAL(req->in.hdr, SMB2_HDR_LENGTH, SMB2_HDR_BODY);
|
||||||
SSVAL(req->in.hdr, SMB2_HDR_EPOCH, 0);
|
SSVAL(req->in.hdr, SMB2_HDR_EPOCH, 0);
|
||||||
|
@ -30,6 +30,22 @@
|
|||||||
#include "ntvfs/ntvfs.h"
|
#include "ntvfs/ntvfs.h"
|
||||||
#include "param/param.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)
|
static int smb2srv_request_destructor(struct smb2srv_request *req)
|
||||||
{
|
{
|
||||||
DLIST_REMOVE(req->smb_conn->requests2.list, 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) {
|
if (p_req->chained_file_handle) {
|
||||||
memcpy(req->_chained_file_handle,
|
memcpy(req->_chained_file_handle,
|
||||||
p_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
|
* TODO: - make sure the length field is 64
|
||||||
* - make sure it's a request
|
* - 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;
|
req->seqnum = UINT64_MAX;
|
||||||
|
|
||||||
|
smb2srv_setup_bufinfo(req);
|
||||||
|
|
||||||
SIVAL(req->in.hdr, 0, SMB2_MAGIC);
|
SIVAL(req->in.hdr, 0, SMB2_MAGIC);
|
||||||
SSVAL(req->in.hdr, SMB2_HDR_LENGTH, SMB2_HDR_BODY);
|
SSVAL(req->in.hdr, SMB2_HDR_LENGTH, SMB2_HDR_BODY);
|
||||||
SSVAL(req->in.hdr, SMB2_HDR_EPOCH, 0);
|
SSVAL(req->in.hdr, SMB2_HDR_EPOCH, 0);
|
||||||
|
@ -254,8 +254,8 @@ struct smbsrv_request {
|
|||||||
/* the sequence number for signing */
|
/* the sequence number for signing */
|
||||||
uint64_t seq_num;
|
uint64_t seq_num;
|
||||||
|
|
||||||
struct request_buffer in;
|
struct smb_request_buffer in;
|
||||||
struct request_buffer out;
|
struct smb_request_buffer out;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum security_types {SEC_SHARE,SEC_USER};
|
enum security_types {SEC_SHARE,SEC_USER};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user