summaryrefslogtreecommitdiff
path: root/source4/smb_server/smb/request.c
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2008-02-14 10:12:33 +1100
committerAndrew Tridgell <tridge@samba.org>2008-02-14 10:12:33 +1100
commite870cfec9f3512b0f1bd3110d7b975652525e28a (patch)
tree2a26a6764bcbc5bd63a8402b6ac1fd7e68be6724 /source4/smb_server/smb/request.c
parent4c01d70a4469ffc25f9a10473cb135bb38a454c7 (diff)
downloadsamba-e870cfec9f3512b0f1bd3110d7b975652525e28a.tar.gz
samba-e870cfec9f3512b0f1bd3110d7b975652525e28a.tar.bz2
samba-e870cfec9f3512b0f1bd3110d7b975652525e28a.zip
Convert SMB and SMB2 code to use a common buffer handling structure
This converts our SMB and SMB2 code to use a common structure "struct request_bufinfo" for information on the buffer bounds of a packet, alignment information and string handling. This allows us to use a common backend for SMB and SMB2 code, while still using all the same string and blob handling functions. Up to now we had been passing a NULL req handle into these common routines from the SMB2 side of the server, which meant that we failed any operation which did a bounds checked string extraction (such as a RenameInformation setinfo call, which is what Vista uses for renaming files) There is still some more work to be done on this - for example we can now remove many of the SMB2 specific buffer handling functions that we had, and use the SMB ones. (This used to be commit ca6d9be6cb6a403a81b18fa6e9a6a0518d7f0f68)
Diffstat (limited to 'source4/smb_server/smb/request.c')
-rw-r--r--source4/smb_server/smb/request.c61
1 files changed, 36 insertions, 25 deletions
diff --git a/source4/smb_server/smb/request.c b/source4/smb_server/smb/request.c
index 8f6d664500..724055499b 100644
--- a/source4/smb_server/smb/request.c
+++ b/source4/smb_server/smb/request.c
@@ -33,6 +33,17 @@
/* we over allocate the data buffer to prevent too many realloc calls */
#define REQ_OVER_ALLOCATION 0
+/* setup the bufinfo used for strings and range checking */
+void smbsrv_setup_bufinfo(struct smbsrv_request *req)
+{
+ req->in.bufinfo.mem_ctx = req;
+ req->in.bufinfo.unicode = (req->flags2 & FLAGS2_UNICODE_STRINGS)?true:false;
+ req->in.bufinfo.align_base = req->in.buffer;
+ req->in.bufinfo.data = req->in.data;
+ req->in.bufinfo.data_size = req->in.data_size;
+}
+
+
static int smbsrv_request_destructor(struct smbsrv_request *req)
{
DLIST_REMOVE(req->smb_conn->requests, req);
@@ -461,13 +472,13 @@ size_t req_append_var_block(struct smbsrv_request *req,
on failure zero is returned and *dest is set to NULL, otherwise the number
of bytes consumed in the packet is returned
*/
-static size_t req_pull_ucs2(struct smbsrv_request *req, const char **dest, const uint8_t *src, int byte_len, uint_t flags)
+static size_t req_pull_ucs2(struct request_bufinfo *bufinfo, const char **dest, const uint8_t *src, int byte_len, uint_t flags)
{
int src_len, src_len2, alignment=0;
ssize_t ret;
char *dest2;
- if (!(flags & STR_NOALIGN) && ucs2_align(req->in.buffer, src, flags)) {
+ if (!(flags & STR_NOALIGN) && ucs2_align(bufinfo->align_base, src, flags)) {
src++;
alignment=1;
if (byte_len != -1) {
@@ -478,7 +489,7 @@ static size_t req_pull_ucs2(struct smbsrv_request *req, const char **dest, const
if (flags & STR_NO_RANGE_CHECK) {
src_len = byte_len;
} else {
- src_len = req->in.data_size - PTR_DIFF(src, req->in.data);
+ src_len = bufinfo->data_size - PTR_DIFF(src, bufinfo->data);
if (byte_len != -1 && src_len > byte_len) {
src_len = byte_len;
}
@@ -491,11 +502,11 @@ static size_t req_pull_ucs2(struct smbsrv_request *req, const char **dest, const
src_len2 = utf16_len_n(src, src_len);
if (src_len2 == 0) {
- *dest = talloc_strdup(req, "");
+ *dest = talloc_strdup(bufinfo->mem_ctx, "");
return src_len2 + alignment;
}
- ret = convert_string_talloc(req, lp_iconv_convenience(global_loadparm), CH_UTF16, CH_UNIX, src, src_len2, (void **)&dest2);
+ ret = convert_string_talloc(bufinfo->mem_ctx, lp_iconv_convenience(global_loadparm), CH_UTF16, CH_UNIX, src, src_len2, (void **)&dest2);
if (ret == -1) {
*dest = NULL;
@@ -519,7 +530,7 @@ static size_t req_pull_ucs2(struct smbsrv_request *req, const char **dest, const
on failure zero is returned and *dest is set to NULL, otherwise the number
of bytes consumed in the packet is returned
*/
-static size_t req_pull_ascii(struct smbsrv_request *req, const char **dest, const uint8_t *src, int byte_len, uint_t flags)
+static size_t req_pull_ascii(struct request_bufinfo *bufinfo, const char **dest, const uint8_t *src, int byte_len, uint_t flags)
{
int src_len, src_len2;
ssize_t ret;
@@ -528,7 +539,7 @@ static size_t req_pull_ascii(struct smbsrv_request *req, const char **dest, cons
if (flags & STR_NO_RANGE_CHECK) {
src_len = byte_len;
} else {
- src_len = req->in.data_size - PTR_DIFF(src, req->in.data);
+ src_len = bufinfo->data_size - PTR_DIFF(src, bufinfo->data);
if (src_len < 0) {
*dest = NULL;
return 0;
@@ -544,7 +555,7 @@ static size_t req_pull_ascii(struct smbsrv_request *req, const char **dest, cons
src_len2++;
}
- ret = convert_string_talloc(req, lp_iconv_convenience(global_loadparm), CH_DOS, CH_UNIX, src, src_len2, (void **)&dest2);
+ ret = convert_string_talloc(bufinfo->mem_ctx, lp_iconv_convenience(global_loadparm), CH_DOS, CH_UNIX, src, src_len2, (void **)&dest2);
if (ret == -1) {
*dest = NULL;
@@ -568,14 +579,14 @@ static size_t req_pull_ascii(struct smbsrv_request *req, const char **dest, cons
on failure zero is returned and *dest is set to NULL, otherwise the number
of bytes consumed in the packet is returned
*/
-size_t req_pull_string(struct smbsrv_request *req, const char **dest, const uint8_t *src, int byte_len, uint_t flags)
+size_t req_pull_string(struct request_bufinfo *bufinfo, const char **dest, const uint8_t *src, int byte_len, uint_t flags)
{
if (!(flags & STR_ASCII) &&
- (((flags & STR_UNICODE) || (req->flags2 & FLAGS2_UNICODE_STRINGS)))) {
- return req_pull_ucs2(req, dest, src, byte_len, flags);
+ (((flags & STR_UNICODE) || bufinfo->unicode))) {
+ return req_pull_ucs2(bufinfo, dest, src, byte_len, flags);
}
- return req_pull_ascii(req, dest, src, byte_len, flags);
+ return req_pull_ascii(bufinfo, dest, src, byte_len, flags);
}
@@ -588,13 +599,13 @@ size_t req_pull_string(struct smbsrv_request *req, const char **dest, const uint
on failure *dest is set to the zero length string. This seems to
match win2000 behaviour
*/
-size_t req_pull_ascii4(struct smbsrv_request *req, const char **dest, const uint8_t *src, uint_t flags)
+size_t req_pull_ascii4(struct request_bufinfo *bufinfo, const char **dest, const uint8_t *src, uint_t flags)
{
ssize_t ret;
- if (PTR_DIFF(src, req->in.data) + 1 > req->in.data_size) {
+ if (PTR_DIFF(src, bufinfo->data) + 1 > bufinfo->data_size) {
/* win2000 treats this as the empty string! */
- (*dest) = talloc_strdup(req, "");
+ (*dest) = talloc_strdup(bufinfo->mem_ctx, "");
return 0;
}
@@ -603,9 +614,9 @@ size_t req_pull_ascii4(struct smbsrv_request *req, const char **dest, const uint
behaviour */
src++;
- ret = req_pull_string(req, dest, src, -1, flags);
+ ret = req_pull_string(bufinfo, dest, src, -1, flags);
if (ret == -1) {
- (*dest) = talloc_strdup(req, "");
+ (*dest) = talloc_strdup(bufinfo->mem_ctx, "");
return 1;
}
@@ -617,30 +628,30 @@ size_t req_pull_ascii4(struct smbsrv_request *req, const char **dest, const uint
return false if any part is outside the data portion of the packet
*/
-bool req_pull_blob(struct smbsrv_request *req, const uint8_t *src, int len, DATA_BLOB *blob)
+bool req_pull_blob(struct request_bufinfo *bufinfo, const uint8_t *src, int len, DATA_BLOB *blob)
{
- if (len != 0 && req_data_oob(req, src, len)) {
+ if (len != 0 && req_data_oob(bufinfo, src, len)) {
return false;
}
- (*blob) = data_blob_talloc(req, src, len);
+ (*blob) = data_blob_talloc(bufinfo->mem_ctx, src, len);
return true;
}
/* check that a lump of data in a request is within the bounds of the data section of
the packet */
-bool req_data_oob(struct smbsrv_request *req, const uint8_t *ptr, uint32_t count)
+bool req_data_oob(struct request_bufinfo *bufinfo, const uint8_t *ptr, uint32_t count)
{
if (count == 0) {
return false;
}
/* be careful with wraparound! */
- if (ptr < req->in.data ||
- ptr >= req->in.data + req->in.data_size ||
- count > req->in.data_size ||
- ptr + count > req->in.data + req->in.data_size) {
+ if (ptr < bufinfo->data ||
+ ptr >= bufinfo->data + bufinfo->data_size ||
+ count > bufinfo->data_size ||
+ ptr + count > bufinfo->data + bufinfo->data_size) {
return true;
}
return false;