summaryrefslogtreecommitdiff
path: root/source4/smb_server/smb
diff options
context:
space:
mode:
Diffstat (limited to 'source4/smb_server/smb')
-rw-r--r--source4/smb_server/smb/config.mk1
-rw-r--r--source4/smb_server/smb/negprot.c3
-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
8 files changed, 115 insertions, 95 deletions
diff --git a/source4/smb_server/smb/config.mk b/source4/smb_server/smb/config.mk
index 22151ebd3b..7927f295b9 100644
--- a/source4/smb_server/smb/config.mk
+++ b/source4/smb_server/smb/config.mk
@@ -16,6 +16,5 @@ OBJ_FILES = \
signing.o
PUBLIC_DEPENDENCIES = \
ntvfs LIBPACKET CREDENTIALS
-LDFLAGS = $(SUBSYSTEM_SMB_SERVER_OUTPUT)
# End SUBSYSTEM SMB_PROTOCOL
#######################
diff --git a/source4/smb_server/smb/negprot.c b/source4/smb_server/smb/negprot.c
index 6d9ff838cb..00ff3862f5 100644
--- a/source4/smb_server/smb/negprot.c
+++ b/source4/smb_server/smb/negprot.c
@@ -466,6 +466,7 @@ static const struct {
void (*proto_reply_fn)(struct smbsrv_request *req, uint16_t choice);
int protocol_level;
} supported_protocols[] = {
+ {"SMB 2.002", "SMB2", reply_smb2, PROTOCOL_SMB2},
{"SMB 2.001", "SMB2", reply_smb2, PROTOCOL_SMB2},
{"NT LANMAN 1.0", "NT1", reply_nt1, PROTOCOL_NT1},
{"NT LM 0.12", "NT1", reply_nt1, PROTOCOL_NT1},
@@ -508,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;
}