summaryrefslogtreecommitdiff
path: root/source4
diff options
context:
space:
mode:
Diffstat (limited to 'source4')
-rw-r--r--source4/libcli/raw/clisession.c20
-rw-r--r--source4/libcli/raw/clitransport.c4
-rw-r--r--source4/libcli/raw/clitree.c6
-rw-r--r--source4/libcli/raw/interfaces.h7
-rw-r--r--source4/libcli/raw/libcliraw.h4
-rw-r--r--source4/libcli/raw/rawfile.c4
-rw-r--r--source4/libcli/raw/rawioctl.c2
-rw-r--r--source4/libcli/raw/rawnegotiate.c10
-rw-r--r--source4/libcli/raw/rawreadwrite.c6
-rw-r--r--source4/libcli/raw/rawrequest.c53
-rw-r--r--source4/libcli/raw/rawsearch.c2
-rw-r--r--source4/libcli/raw/rawsetfileinfo.c11
-rw-r--r--source4/libcli/raw/request.h19
-rw-r--r--source4/libcli/raw/smb_signing.c6
-rw-r--r--source4/libcli/smb2/connect.c2
-rw-r--r--source4/libcli/smb2/getinfo.c45
-rw-r--r--source4/libcli/smb2/request.c42
-rw-r--r--source4/libcli/smb2/setinfo.c6
-rw-r--r--source4/libcli/smb2/smb2.h8
-rw-r--r--source4/libcli/smb2/smb2_calls.h24
-rw-r--r--source4/libcli/smb2/transport.c2
-rw-r--r--source4/ntvfs/posix/pvfs_setfileinfo.c44
-rw-r--r--source4/smb_server/blob.c45
-rw-r--r--source4/smb_server/smb/negprot.c2
-rw-r--r--source4/smb_server/smb/nttrans.c6
-rw-r--r--source4/smb_server/smb/receive.c6
-rw-r--r--source4/smb_server/smb/reply.c94
-rw-r--r--source4/smb_server/smb/request.c64
-rw-r--r--source4/smb_server/smb/search.c12
-rw-r--r--source4/smb_server/smb/trans2.c24
-rw-r--r--source4/smb_server/smb2/fileinfo.c49
-rw-r--r--source4/smb_server/smb2/negprot.c11
-rw-r--r--source4/smb_server/smb2/receive.c20
-rw-r--r--source4/smb_server/smb2/tcon.c2
-rw-r--r--source4/smb_server/smb_server.h4
-rw-r--r--source4/torture/smb2/scan.c15
36 files changed, 446 insertions, 235 deletions
diff --git a/source4/libcli/raw/clisession.c b/source4/libcli/raw/clisession.c
index 617131c53c..55cb3ef305 100644
--- a/source4/libcli/raw/clisession.c
+++ b/source4/libcli/raw/clisession.c
@@ -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:
diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c
index 62c32d3058..288f0612de 100644
--- a/source4/libcli/raw/clitransport.c
+++ b/source4/libcli/raw/clitransport.c
@@ -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;
}
diff --git a/source4/libcli/raw/clitree.c b/source4/libcli/raw/clitree.c
index 35f3335322..507bde999a 100644
--- a/source4/libcli/raw/clitree.c
+++ b/source4/libcli/raw/clitree.c
@@ -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;
diff --git a/source4/libcli/raw/interfaces.h b/source4/libcli/raw/interfaces.h
index ce6323f2e5..24e8ad4afc 100644
--- a/source4/libcli/raw/interfaces.h
+++ b/source4/libcli/raw/interfaces.h
@@ -902,7 +902,10 @@ enum smb_setfileinfo_level {
RAW_SFILEINFO_1029 = SMB_SFILEINFO_1029,
RAW_SFILEINFO_1032 = SMB_SFILEINFO_1032,
RAW_SFILEINFO_1039 = SMB_SFILEINFO_1039,
- RAW_SFILEINFO_1040 = SMB_SFILEINFO_1040
+ RAW_SFILEINFO_1040 = SMB_SFILEINFO_1040,
+
+ /* cope with breakage in SMB2 */
+ RAW_SFILEINFO_RENAME_INFORMATION_SMB2 = SMB_SFILEINFO_RENAME_INFORMATION|0x80000000,
};
/* union used in setfileinfo() and setpathinfo() calls */
@@ -1000,7 +1003,7 @@ union smb_setfileinfo {
struct {
union smb_handle_or_path file;
uint8_t overwrite;
- uint32_t root_fid;
+ uint64_t root_fid;
const char *new_name;
} in;
} rename_information;
diff --git a/source4/libcli/raw/libcliraw.h b/source4/libcli/raw/libcliraw.h
index 0032eb4e94..7111649fc1 100644
--- a/source4/libcli/raw/libcliraw.h
+++ b/source4/libcli/raw/libcliraw.h
@@ -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
diff --git a/source4/libcli/raw/rawfile.c b/source4/libcli/raw/rawfile.c
index 3b6ca68526..d9383401b7 100644
--- a/source4/libcli/raw/rawfile.c
+++ b/source4/libcli/raw/rawfile.c
@@ -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;
diff --git a/source4/libcli/raw/rawioctl.c b/source4/libcli/raw/rawioctl.c
index 9205f84e86..957e554c6b 100644
--- a/source4/libcli/raw/rawioctl.c
+++ b/source4/libcli/raw/rawioctl.c
@@ -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);
}
diff --git a/source4/libcli/raw/rawnegotiate.c b/source4/libcli/raw/rawnegotiate.c
index 1f5e34779b..ec2ada53ff 100644
--- a/source4/libcli/raw/rawnegotiate.c
+++ b/source4/libcli/raw/rawnegotiate.c
@@ -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 */
diff --git a/source4/libcli/raw/rawreadwrite.c b/source4/libcli/raw/rawreadwrite.c
index b0c49ddab7..2005e36e04 100644
--- a/source4/libcli/raw/rawreadwrite.c
+++ b/source4/libcli/raw/rawreadwrite.c
@@ -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;
diff --git a/source4/libcli/raw/rawrequest.c b/source4/libcli/raw/rawrequest.c
index 3551e5d441..355d092583 100644
--- a/source4/libcli/raw/rawrequest.c
+++ b/source4/libcli/raw/rawrequest.c
@@ -34,6 +34,20 @@
/* 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.flags = 0;
+ if (req->flags2 & FLAGS2_UNICODE_STRINGS) {
+ req->in.bufinfo.flags = BUFINFO_FLAG_UNICODE;
+ }
+ 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 +312,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 +561,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 +575,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 +614,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 +657,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->flags & BUFINFO_FLAG_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 +675,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 +694,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 +711,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;
}
diff --git a/source4/libcli/raw/rawsearch.c b/source4/libcli/raw/rawsearch.c
index 33fa90d68d..fb2b09467c 100644
--- a/source4/libcli/raw/rawsearch.c
+++ b/source4/libcli/raw/rawsearch.c
@@ -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;
diff --git a/source4/libcli/raw/rawsetfileinfo.c b/source4/libcli/raw/rawsetfileinfo.c
index a9a1a3547e..f1e4ee3686 100644
--- a/source4/libcli/raw/rawsetfileinfo.c
+++ b/source4/libcli/raw/rawsetfileinfo.c
@@ -75,6 +75,16 @@ bool smb_raw_setfileinfo_passthru(TALLOC_CTX *mem_ctx,
SIVAL(blob->data, 8, len - 2);
return true;
+ case RAW_SFILEINFO_RENAME_INFORMATION_SMB2:
+ NEED_BLOB(20);
+ SIVAL(blob->data, 0, parms->rename_information.in.overwrite);
+ SBVAL(blob->data, 8, parms->rename_information.in.root_fid);
+ len = smbcli_blob_append_string(NULL, mem_ctx, blob,
+ parms->rename_information.in.new_name,
+ STR_UNICODE|STR_TERMINATE);
+ SIVAL(blob->data, 16, len - 2);
+ return true;
+
case RAW_SFILEINFO_POSITION_INFORMATION:
NEED_BLOB(8);
SBVAL(blob->data, 0, parms->position_information.in.position);
@@ -229,6 +239,7 @@ static bool smb_raw_setinfo_backend(struct smbcli_tree *tree,
case RAW_SFILEINFO_UNIX_LINK:
case RAW_SFILEINFO_UNIX_HLINK:
+ case RAW_SFILEINFO_RENAME_INFORMATION_SMB2:
break;
}
diff --git a/source4/libcli/raw/request.h b/source4/libcli/raw/request.h
index 803a450e3c..2a572e58ee 100644
--- a/source4/libcli/raw/request.h
+++ b/source4/libcli/raw/request.h
@@ -22,11 +22,25 @@
#include "libcli/raw/signing.h"
+#define BUFINFO_FLAG_UNICODE 0x0001
+#define BUFINFO_FLAG_SMB2 0x0002
+
+/*
+ buffer limit structure used by both SMB and SMB2
+ */
+struct request_bufinfo {
+ TALLOC_CTX *mem_ctx;
+ uint32_t flags;
+ 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 +70,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
diff --git a/source4/libcli/raw/smb_signing.c b/source4/libcli/raw/smb_signing.c
index 0053710aaf..4acfb9d16d 100644
--- a/source4/libcli/raw/smb_signing.c
+++ b/source4/libcli/raw/smb_signing.c
@@ -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];
diff --git a/source4/libcli/smb2/connect.c b/source4/libcli/smb2/connect.c
index 535df11d9d..85ddafc031 100644
--- a/source4/libcli/smb2/connect.c
+++ b/source4/libcli/smb2/connect.c
@@ -133,7 +133,7 @@ static void continue_socket(struct composite_context *creq)
state->negprot.in.security_mode = 0;
state->negprot.in.capabilities = 0;
unix_to_nt_time(&state->negprot.in.start_time, time(NULL));
- dialects[0] = 0;
+ dialects[0] = SMB2_DIALECT_REVISION;
state->negprot.in.dialects = dialects;
req = smb2_negprot_send(transport, &state->negprot);
diff --git a/source4/libcli/smb2/getinfo.c b/source4/libcli/smb2/getinfo.c
index 0665dd441c..e9f47140f5 100644
--- a/source4/libcli/smb2/getinfo.c
+++ b/source4/libcli/smb2/getinfo.c
@@ -30,21 +30,27 @@
struct smb2_request *smb2_getinfo_send(struct smb2_tree *tree, struct smb2_getinfo *io)
{
struct smb2_request *req;
+ NTSTATUS status;
- req = smb2_request_init_tree(tree, SMB2_OP_GETINFO, 0x28, false, 0);
+ req = smb2_request_init_tree(tree, SMB2_OP_GETINFO, 0x28, true,
+ io->in.blob.length);
if (req == NULL) return NULL;
- /* this seems to be a bug, they use 0x29 but only send 0x28 bytes */
- SSVAL(req->out.body, 0x00, 0x29);
-
- SSVAL(req->out.body, 0x02, io->in.level);
- SIVAL(req->out.body, 0x04, io->in.max_response_size);
- SIVAL(req->out.body, 0x08, io->in.unknown1);
- SIVAL(req->out.body, 0x0C, io->in.unknown2);
- SIVAL(req->out.body, 0x10, io->in.flags);
- SIVAL(req->out.body, 0x14, io->in.flags2);
+ SCVAL(req->out.body, 0x02, io->in.info_type);
+ SCVAL(req->out.body, 0x03, io->in.info_class);
+ SIVAL(req->out.body, 0x04, io->in.output_buffer_length);
+ SIVAL(req->out.body, 0x0C, io->in.reserved);
+ SIVAL(req->out.body, 0x08, io->in.input_buffer_length);
+ SIVAL(req->out.body, 0x10, io->in.additional_information);
+ SIVAL(req->out.body, 0x14, io->in.getinfo_flags);
smb2_push_handle(req->out.body+0x18, &io->in.file.handle);
+ /* this blob is used for quota queries */
+ status = smb2_push_o32s32_blob(&req->out, 0x08, io->in.blob);
+ if (!NT_STATUS_IS_OK(status)) {
+ talloc_free(req);
+ return NULL;
+ }
smb2_transport_send(req);
return req;
@@ -116,15 +122,17 @@ struct smb2_request *smb2_getinfo_file_send(struct smb2_tree *tree, union smb_fi
}
ZERO_STRUCT(b);
- b.in.max_response_size = 0x10000;
- b.in.file.handle = io->generic.in.file.handle;
- b.in.level = smb2_level;
+ b.in.info_type = smb2_level & 0xFF;
+ b.in.info_class = smb2_level >> 8;
+ b.in.output_buffer_length = 0x10000;
+ b.in.input_buffer_length = 0;
+ b.in.file.handle = io->generic.in.file.handle;
if (io->generic.level == RAW_FILEINFO_SEC_DESC) {
- b.in.flags = io->query_secdesc.in.secinfo_flags;
+ b.in.additional_information = io->query_secdesc.in.secinfo_flags;
}
if (io->generic.level == RAW_FILEINFO_SMB2_ALL_EAS) {
- b.in.flags2 = io->all_eas.in.continue_flags;
+ b.in.getinfo_flags = io->all_eas.in.continue_flags;
}
return smb2_getinfo_send(tree, &b);
@@ -172,9 +180,10 @@ struct smb2_request *smb2_getinfo_fs_send(struct smb2_tree *tree, union smb_fsin
}
ZERO_STRUCT(b);
- b.in.max_response_size = 0x10000;
- b.in.file.handle = io->generic.handle;
- b.in.level = smb2_level;
+ b.in.output_buffer_length = 0x10000;
+ b.in.file.handle = io->generic.handle;
+ b.in.info_type = smb2_level & 0xFF;
+ b.in.info_class = smb2_level >> 8;
return smb2_getinfo_send(tree, &b);
}
diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c
index 46ec24145f..7a0311f886 100644
--- a/source4/libcli/smb2/request.c
+++ b/source4/libcli/smb2/request.c
@@ -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.flags = BUFINFO_FLAG_UNICODE | BUFINFO_FLAG_SMB2;
+ 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
*/
@@ -534,6 +549,33 @@ NTSTATUS smb2_pull_o32s32_blob(struct smb2_request_buffer *buf, TALLOC_CTX *mem_
}
/*
+ pull a uint16_t ofs/ uint32_t length/blob triple from a data blob
+ the ptr points to the start of the offset/length pair
+
+ In this varient the uint16_t is padded by an extra 2 bytes, making
+ the size aligned on 4 byte boundary
+*/
+NTSTATUS smb2_pull_o16As32_blob(struct smb2_request_buffer *buf, TALLOC_CTX *mem_ctx, uint8_t *ptr, DATA_BLOB *blob)
+{
+ uint32_t ofs, size;
+ if (smb2_oob(buf, ptr, 8)) {
+ return NT_STATUS_BUFFER_TOO_SMALL;
+ }
+ ofs = SVAL(ptr, 0);
+ size = IVAL(ptr, 4);
+ if (ofs == 0 || size == 0) {
+ *blob = data_blob(NULL, 0);
+ return NT_STATUS_OK;
+ }
+ if (smb2_oob(buf, buf->hdr + ofs, size)) {
+ return NT_STATUS_BUFFER_TOO_SMALL;
+ }
+ *blob = data_blob_talloc(mem_ctx, buf->hdr + ofs, size);
+ NT_STATUS_HAVE_NO_MEMORY(blob->data);
+ return NT_STATUS_OK;
+}
+
+/*
pull a uint32_t length/ uint32_t ofs/blob triple from a data blob
the ptr points to the start of the offset/length pair
*/
diff --git a/source4/libcli/smb2/setinfo.c b/source4/libcli/smb2/setinfo.c
index d942568a2d..a6e22d9a68 100644
--- a/source4/libcli/smb2/setinfo.c
+++ b/source4/libcli/smb2/setinfo.c
@@ -92,6 +92,12 @@ struct smb2_request *smb2_setinfo_file_send(struct smb2_tree *tree, union smb_se
ZERO_STRUCT(b);
b.in.level = smb2_level;
b.in.file.handle = io->generic.in.file.handle;
+
+ /* change levels so the parsers know it is SMB2 */
+ if (io->generic.level == RAW_SFILEINFO_RENAME_INFORMATION) {
+ io->generic.level = RAW_SFILEINFO_RENAME_INFORMATION_SMB2;
+ }
+
if (!smb_raw_setfileinfo_passthru(tree, io->generic.level, io, &b.in.blob)) {
return NULL;
}
diff --git a/source4/libcli/smb2/smb2.h b/source4/libcli/smb2/smb2.h
index db13ab69b3..726df64090 100644
--- a/source4/libcli/smb2/smb2.h
+++ b/source4/libcli/smb2/smb2.h
@@ -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;
};
@@ -195,6 +200,9 @@ struct smb2_request {
#define SMB2_MAGIC 0x424D53FE /* 0xFE 'S' 'M' 'B' */
+/* the dialect we support */
+#define SMB2_DIALECT_REVISION 0x202
+
/* SMB2 negotiate security_mode */
#define SMB2_NEGOTIATE_SIGNING_ENABLED 0x01
#define SMB2_NEGOTIATE_SIGNING_REQUIRED 0x02
diff --git a/source4/libcli/smb2/smb2_calls.h b/source4/libcli/smb2/smb2_calls.h
index f2e3019d83..f66236af30 100644
--- a/source4/libcli/smb2/smb2_calls.h
+++ b/source4/libcli/smb2/smb2_calls.h
@@ -56,6 +56,13 @@ struct smb2_negprot {
#define SMB2_GETINFO_FILE 0x01
#define SMB2_GETINFO_FS 0x02
#define SMB2_GETINFO_SECURITY 0x03
+#define SMB2_GETINFO_QUOTA 0x04
+
+#define SMB2_GETINFO_ADD_OWNER_SECURITY 0x01
+#define SMB2_GETINFO_ADD_GROUP_SECURITY 0x02
+#define SMB2_GETINFO_ADD_DACL_SECURITY 0x04
+#define SMB2_GETINFO_ADD_SACL_SECURITY 0x08
+#define SMB2_GETINFO_ADD_LABEL_SECURITY 0x10
/* NOTE! the getinfo fs and file levels exactly match up with the
'passthru' SMB levels, which are levels >= 1000. The SMB2 client
@@ -64,14 +71,17 @@ struct smb2_negprot {
struct smb2_getinfo {
struct {
/* static body buffer 40 (0x28) bytes */
- /* uint16_t buffer_code; 0x29 = 0x28 + 1 (why???) */
- uint16_t level;
- uint32_t max_response_size;
- uint32_t unknown1;
- uint32_t unknown2;
- uint32_t flags; /* level specific */
- uint32_t flags2; /* used by all_eas level */
+ /* uint16_t buffer_code; 0x29 = 0x28 + 1 */
+ uint8_t info_type;
+ uint8_t info_class;
+ uint32_t output_buffer_length;
+ /* uint32_t input_buffer_offset; */
+ uint32_t reserved;
+ uint32_t input_buffer_length;
+ uint32_t additional_information; /* SMB2_GETINFO_ADD_* */
+ uint32_t getinfo_flags; /* level specific */
union smb_handle file;
+ DATA_BLOB blob;
} in;
struct {
diff --git a/source4/libcli/smb2/transport.c b/source4/libcli/smb2/transport.c
index dceb78382a..1d601fdbfe 100644
--- a/source4/libcli/smb2/transport.c
+++ b/source4/libcli/smb2/transport.c
@@ -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);
diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c
index 340913cd4d..9c78699edb 100644
--- a/source4/ntvfs/posix/pvfs_setfileinfo.c
+++ b/source4/ntvfs/posix/pvfs_setfileinfo.c
@@ -63,6 +63,11 @@ static uint32_t pvfs_setfileinfo_access(union smb_setfileinfo *info)
}
break;
+ case RAW_SFILEINFO_RENAME_INFORMATION:
+ case RAW_SFILEINFO_RENAME_INFORMATION_SMB2:
+ needed = SEC_STD_DELETE;
+ break;
+
default:
needed = SEC_FILE_WRITE_ATTRIBUTE;
break;
@@ -84,7 +89,8 @@ static NTSTATUS pvfs_setfileinfo_rename(struct pvfs_state *pvfs,
char *new_name, *p;
/* renames are only allowed within a directory */
- if (strchr_m(info->rename_information.in.new_name, '\\')) {
+ if (strchr_m(info->rename_information.in.new_name, '\\') &&
+ (req->ctx->protocol != PROTOCOL_SMB2)) {
return NT_STATUS_NOT_SUPPORTED;
}
@@ -98,24 +104,32 @@ static NTSTATUS pvfs_setfileinfo_rename(struct pvfs_state *pvfs,
return NT_STATUS_INVALID_PARAMETER;
}
- /* w2k3 does not appear to allow relative rename */
- if (info->rename_information.in.root_fid != 0) {
+ /* w2k3 does not appear to allow relative rename. On SMB2, vista sends it sometimes,
+ but I suspect it is just uninitialised memory */
+ if (info->rename_information.in.root_fid != 0 &&
+ (req->ctx->protocol != PROTOCOL_SMB2)) {
return NT_STATUS_INVALID_PARAMETER;
}
/* construct the fully qualified windows name for the new file name */
- new_name = talloc_strdup(req, name->original_name);
- if (new_name == NULL) {
- return NT_STATUS_NO_MEMORY;
- }
- p = strrchr_m(new_name, '\\');
- if (p == NULL) {
- return NT_STATUS_OBJECT_NAME_INVALID;
- }
- *p = 0;
+ if (req->ctx->protocol == PROTOCOL_SMB2) {
+ /* SMB2 sends the full path of the new name */
+ new_name = talloc_asprintf(req, "\\%s", info->rename_information.in.new_name);
+ } else {
+ new_name = talloc_strdup(req, name->original_name);
+ if (new_name == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ p = strrchr_m(new_name, '\\');
+ if (p == NULL) {
+ return NT_STATUS_OBJECT_NAME_INVALID;
+ } else {
+ *p = 0;
+ }
- new_name = talloc_asprintf(req, "%s\\%s", new_name,
- info->rename_information.in.new_name);
+ new_name = talloc_asprintf(req, "%s\\%s", new_name,
+ info->rename_information.in.new_name);
+ }
if (new_name == NULL) {
return NT_STATUS_NO_MEMORY;
}
@@ -369,6 +383,7 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs,
break;
case RAW_SFILEINFO_RENAME_INFORMATION:
+ case RAW_SFILEINFO_RENAME_INFORMATION_SMB2:
return pvfs_setfileinfo_rename(pvfs, req, h->name,
info);
@@ -566,6 +581,7 @@ NTSTATUS pvfs_setpathinfo(struct ntvfs_module_context *ntvfs,
return NT_STATUS_OK;
case RAW_SFILEINFO_RENAME_INFORMATION:
+ case RAW_SFILEINFO_RENAME_INFORMATION_SMB2:
return pvfs_setfileinfo_rename(pvfs, req, name,
info);
diff --git a/source4/smb_server/blob.c b/source4/smb_server/blob.c
index 2b870118ba..8c813204f3 100644
--- a/source4/smb_server/blob.c
+++ b/source4/smb_server/blob.c
@@ -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,9 +521,9 @@ 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;
+ uint32_t len, ofs;
DATA_BLOB str_blob;
switch (level) {
@@ -560,21 +560,38 @@ 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);
-
st->rename_information.in.overwrite = CVAL(blob->data, 0);
st->rename_information.in.root_fid = IVAL(blob->data, 4);
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,
+ ofs = 12;
+ str_blob = *blob;
+ str_blob.length = MIN(str_blob.length, ofs+len);
+ smbsrv_blob_pull_string(bufinfo, &str_blob, ofs,
+ &st->rename_information.in.new_name,
+ STR_UNICODE);
+ if (st->rename_information.in.new_name == NULL) {
+ return NT_STATUS_FOOBAR;
+ }
+
+ return NT_STATUS_OK;
+
+ case RAW_SFILEINFO_RENAME_INFORMATION_SMB2:
+ /* SMB2 uses a different format for rename information */
+ if (!bufinfo) {
+ return NT_STATUS_INTERNAL_ERROR;
+ }
+ BLOB_CHECK_MIN_SIZE(blob, 20);
+ st->rename_information.in.overwrite = CVAL(blob->data, 0);
+ st->rename_information.in.root_fid = BVAL(blob->data, 8);
+ len = IVAL(blob->data,16);
+ ofs = 20;
+ str_blob = *blob;
+ str_blob.length = MIN(str_blob.length, ofs+len);
+ smbsrv_blob_pull_string(bufinfo, &str_blob, ofs,
&st->rename_information.in.new_name,
STR_UNICODE);
if (st->rename_information.in.new_name == NULL) {
diff --git a/source4/smb_server/smb/negprot.c b/source4/smb_server/smb/negprot.c
index b57e5e1d64..00ff3862f5 100644
--- a/source4/smb_server/smb/negprot.c
+++ b/source4/smb_server/smb/negprot.c
@@ -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;
diff --git a/source4/smb_server/smb/nttrans.c b/source4/smb_server/smb/nttrans.c
index dd2ec15e39..f6edc407d6 100644
--- a/source4/smb_server/smb/nttrans.c
+++ b/source4/smb_server/smb/nttrans.c
@@ -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;
}
diff --git a/source4/smb_server/smb/receive.c b/source4/smb_server/smb/receive.c
index 3f590decca..e3d247cbc0 100644
--- a/source4/smb_server/smb/receive.c
+++ b/source4/smb_server/smb/receive.c
@@ -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);
diff --git a/source4/smb_server/smb/reply.c b/source4/smb_server/smb/reply.c
index aff0587bc6..40cad91062 100644
--- a/source4/smb_server/smb/reply.c
+++ b/source4/smb_server/smb/reply.c
@@ -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;
diff --git a/source4/smb_server/smb/request.c b/source4/smb_server/smb/request.c
index 8f6d664500..d7f3793f23 100644
--- a/source4/smb_server/smb/request.c
+++ b/source4/smb_server/smb/request.c
@@ -33,6 +33,20 @@
/* 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.flags = 0;
+ if (req->flags2 & FLAGS2_UNICODE_STRINGS) {
+ req->in.bufinfo.flags |= BUFINFO_FLAG_UNICODE;
+ }
+ 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 +475,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 +492,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 +505,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 +533,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 +542,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 +558,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 +582,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->flags & BUFINFO_FLAG_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 +602,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 +617,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 +631,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;
diff --git a/source4/smb_server/smb/search.c b/source4/smb_server/smb/search.c
index ccf2ff7365..90b2331271 100644
--- a/source4/smb_server/smb/search.c
+++ b/source4/smb_server/smb/search.c
@@ -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;
}
diff --git a/source4/smb_server/smb/trans2.c b/source4/smb_server/smb/trans2.c
index 45ea234d09..3336169bb0 100644
--- a/source4/smb_server/smb/trans2.c
+++ b/source4/smb_server/smb/trans2.c
@@ -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, &params) ||
- !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, &params) ||
+ !req_pull_blob(&req->in.bufinfo, req->in.hdr + data_ofs, data_count, &data)) {
smbsrv_send_error(req, NT_STATUS_INVALID_PARAMETER);
return;
}
diff --git a/source4/smb_server/smb2/fileinfo.c b/source4/smb_server/smb2/fileinfo.c
index 00c455e351..d6db61eaba 100644
--- a/source4/smb_server/smb2/fileinfo.c
+++ b/source4/smb_server/smb2/fileinfo.c
@@ -79,19 +79,21 @@ static NTSTATUS smb2srv_getinfo_file_send(struct smb2srv_getinfo_op *op)
static NTSTATUS smb2srv_getinfo_file(struct smb2srv_getinfo_op *op, uint8_t smb2_level)
{
union smb_fileinfo *io;
+ uint16_t level;
io = talloc(op, union smb_fileinfo);
NT_STATUS_HAVE_NO_MEMORY(io);
- switch (op->info->in.level) {
+ level = op->info->in.info_type | (op->info->in.info_class << 8);
+ switch (level) {
case RAW_FILEINFO_SMB2_ALL_EAS:
- io->all_eas.level = op->info->in.level;
+ io->all_eas.level = level;
io->all_eas.in.file.ntvfs = op->info->in.file.ntvfs;
- io->all_eas.in.continue_flags = op->info->in.flags2;
+ io->all_eas.in.continue_flags = op->info->in.getinfo_flags;
break;
case RAW_FILEINFO_SMB2_ALL_INFORMATION:
- io->all_info2.level = op->info->in.level;
+ io->all_info2.level = level;
io->all_info2.in.file.ntvfs = op->info->in.file.ntvfs;
break;
@@ -166,7 +168,7 @@ static NTSTATUS smb2srv_getinfo_security(struct smb2srv_getinfo_op *op, uint8_t
io->query_secdesc.level = RAW_FILEINFO_SEC_DESC;
io->query_secdesc.in.file.ntvfs = op->info->in.file.ntvfs;
- io->query_secdesc.in.secinfo_flags = op->info->in.flags;
+ io->query_secdesc.in.secinfo_flags = op->info->in.additional_information;
op->io_ptr = io;
op->send_fn = smb2srv_getinfo_security_send;
@@ -179,23 +181,17 @@ static NTSTATUS smb2srv_getinfo_security(struct smb2srv_getinfo_op *op, uint8_t
static NTSTATUS smb2srv_getinfo_backend(struct smb2srv_getinfo_op *op)
{
- uint8_t smb2_class;
- uint8_t smb2_level;
-
- smb2_class = 0xFF & op->info->in.level;
- smb2_level = 0xFF & (op->info->in.level>>8);
-
- switch (smb2_class) {
+ switch (op->info->in.info_type) {
case SMB2_GETINFO_FILE:
- return smb2srv_getinfo_file(op, smb2_level);
+ return smb2srv_getinfo_file(op, op->info->in.info_class);
case SMB2_GETINFO_FS:
- return smb2srv_getinfo_fs(op, smb2_level);
+ return smb2srv_getinfo_fs(op, op->info->in.info_class);
case SMB2_GETINFO_SECURITY:
- return smb2srv_getinfo_security(op, smb2_level);
+ return smb2srv_getinfo_security(op, op->info->in.info_class);
- case 0x04:
+ case SMB2_GETINFO_QUOTA:
return NT_STATUS_NOT_SUPPORTED;
}
@@ -217,13 +213,15 @@ void smb2srv_getinfo_recv(struct smb2srv_request *req)
op->send_fn = NULL;
SMB2SRV_SETUP_NTVFS_REQUEST(smb2srv_getinfo_send, NTVFS_ASYNC_STATE_MAY_ASYNC);
- info->in.level = SVAL(req->in.body, 0x02);
- info->in.max_response_size = IVAL(req->in.body, 0x04);
- info->in.unknown1 = IVAL(req->in.body, 0x08);
- info->in.unknown2 = IVAL(req->in.body, 0x0C);
- info->in.flags = IVAL(req->in.body, 0x10);
- info->in.flags2 = IVAL(req->in.body, 0x14);
+ info->in.info_type = CVAL(req->in.body, 0x02);
+ info->in.info_class = CVAL(req->in.body, 0x03);
+ info->in.output_buffer_length = IVAL(req->in.body, 0x04);
+ info->in.reserved = IVAL(req->in.body, 0x0C);
+ info->in.additional_information = IVAL(req->in.body, 0x10);
+ info->in.getinfo_flags = IVAL(req->in.body, 0x14);
info->in.file.ntvfs = smb2srv_pull_handle(req, req->in.body, 0x18);
+ SMB2SRV_CHECK(smb2_pull_o16As32_blob(&req->in, op,
+ req->in.body+0x08, &info->in.blob));
SMB2SRV_CHECK_FILE_HANDLE(info->in.file.ntvfs);
SMB2SRV_CALL_NTVFS_BACKEND(smb2srv_getinfo_backend(op));
@@ -266,9 +264,14 @@ static NTSTATUS smb2srv_setinfo_file(struct smb2srv_setinfo_op *op, uint8_t smb2
io->generic.level = smb2_level + 1000;
io->generic.in.file.ntvfs = op->info->in.file.ntvfs;
+ /* handle cases that don't map directly */
+ if (io->generic.level == RAW_SFILEINFO_RENAME_INFORMATION) {
+ io->generic.level = RAW_SFILEINFO_RENAME_INFORMATION_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);
diff --git a/source4/smb_server/smb2/negprot.c b/source4/smb_server/smb2/negprot.c
index 7c295c05ab..5bbd7f7d5e 100644
--- a/source4/smb_server/smb2/negprot.c
+++ b/source4/smb_server/smb2/negprot.c
@@ -93,12 +93,14 @@ static NTSTATUS smb2srv_negprot_backend(struct smb2srv_request *req, struct smb2
struct timeval current_time;
struct timeval boot_time;
- /* we only do dialect 0 for now */
+ /* we only do one dialect for now */
if (io->in.dialect_count < 1) {
return NT_STATUS_NOT_SUPPORTED;
}
- if (io->in.dialects[0] != 0) {
+ if (io->in.dialects[0] != 0 &&
+ io->in.dialects[0] != SMB2_DIALECT_REVISION) {
DEBUG(0,("Got unexpected SMB2 dialect %u\n", io->in.dialects[0]));
+ return NT_STATUS_NOT_SUPPORTED;
}
req->smb_conn->negotiate.protocol = PROTOCOL_SMB2;
@@ -108,8 +110,7 @@ static NTSTATUS smb2srv_negprot_backend(struct smb2srv_request *req, struct smb2
ZERO_STRUCT(io->out);
io->out.security_mode = 0; /* no signing yet */
- /* choose the first dialect offered for now */
- io->out.dialect_revision = io->in.dialects[0];
+ io->out.dialect_revision = SMB2_DIALECT_REVISION;
io->out.capabilities = 0;
io->out.max_transact_size = 0x10000;
io->out.max_read_size = 0x10000;
@@ -238,6 +239,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);
diff --git a/source4/smb_server/smb2/receive.c b/source4/smb_server/smb2/receive.c
index 393b3f0cc5..dea7c9e79e 100644
--- a/source4/smb_server/smb2/receive.c
+++ b/source4/smb_server/smb2/receive.c
@@ -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.flags = BUFINFO_FLAG_UNICODE | BUFINFO_FLAG_SMB2;
+ 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
diff --git a/source4/smb_server/smb2/tcon.c b/source4/smb_server/smb2/tcon.c
index b375ce6b4b..50094b806d 100644
--- a/source4/smb_server/smb2/tcon.c
+++ b/source4/smb_server/smb2/tcon.c
@@ -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);
diff --git a/source4/smb_server/smb_server.h b/source4/smb_server/smb_server.h
index bb0673b7d0..776fe1b71b 100644
--- a/source4/smb_server/smb_server.h
+++ b/source4/smb_server/smb_server.h
@@ -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};
diff --git a/source4/torture/smb2/scan.c b/source4/torture/smb2/scan.c
index 84be11c047..0f4c9fefdf 100644
--- a/source4/torture/smb2/scan.c
+++ b/source4/torture/smb2/scan.c
@@ -68,19 +68,21 @@ bool torture_smb2_getinfo_scan(struct torture_context *torture)
ZERO_STRUCT(io);
- io.in.max_response_size = 0xFFFF;
+ io.in.output_buffer_length = 0xFFFF;
for (c=1;c<5;c++) {
for (i=0;i<0x100;i++) {
- io.in.level = (i<<8) | c;
+ io.in.info_type = c;
+ io.in.info_class = i;
io.in.file.handle = fhandle;
status = smb2_getinfo(tree, torture, &io);
if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS) &&
!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER) &&
!NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
- printf("file level 0x%04x is %ld bytes - %s\n",
- io.in.level, (long)io.out.blob.length, nt_errstr(status));
+ printf("file level 0x%02x:%02x is %ld bytes - %s\n",
+ io.in.info_type, io.in.info_class,
+ (long)io.out.blob.length, nt_errstr(status));
dump_data(1, io.out.blob.data, io.out.blob.length);
}
@@ -89,8 +91,9 @@ bool torture_smb2_getinfo_scan(struct torture_context *torture)
if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS) &&
!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER) &&
!NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
- printf("dir level 0x%04x is %ld bytes - %s\n",
- io.in.level, (long)io.out.blob.length, nt_errstr(status));
+ printf("dir level 0x%02x:%02x is %ld bytes - %s\n",
+ io.in.info_type, io.in.info_class,
+ (long)io.out.blob.length, nt_errstr(status));
dump_data(1, io.out.blob.data, io.out.blob.length);
}
}