From 05c0adf433cd8d51226075cdc82099a815b2b355 Mon Sep 17 00:00:00 2001 From: Ralph Wuerthner Date: Wed, 10 Jul 2013 08:59:58 +0200 Subject: [PATCH 1/5] s3:smbd: return NT_STATUS_INFO_LENGTH_MISMATCH for GetInfo in case output_buffer_length is too small --- source3/smbd/smb2_getinfo.c | 5 +++++ 1 files changed, 5 insertions(+), 0 deletions(-) diff --git a/source3/smbd/smb2_getinfo.c b/source3/smbd/smb2_getinfo.c index 5616c84..ec0bad0 100644 --- a/source3/smbd/smb2_getinfo.c +++ b/source3/smbd/smb2_getinfo.c @@ -498,6 +498,11 @@ static struct tevent_req *smbd_smb2_getinfo_send(TALLOC_CTX *mem_ctx, return tevent_req_post(req, ev); } + if (state->out_output_buffer.length > in_output_buffer_length) { + tevent_req_nterror(req, NT_STATUS_INFO_LENGTH_MISMATCH); + return tevent_req_post(req, ev); + } + tevent_req_done(req); return tevent_req_post(req, ev); } -- 1.7.1 From 409270905e48339087156bf53dffbd661bcc4d2a Mon Sep 17 00:00:00 2001 From: Ralph Wuerthner Date: Fri, 5 Jul 2013 11:03:16 +0200 Subject: [PATCH 2/5] s3:smbd: allow GetInfo responses with STATUS_BUFFER_OVERFLOW to return partial, but valid data --- source3/smbd/smb2_getinfo.c | 13 ++++++++++--- 1 files changed, 10 insertions(+), 3 deletions(-) diff --git a/source3/smbd/smb2_getinfo.c b/source3/smbd/smb2_getinfo.c index ec0bad0..7a41b19 100644 --- a/source3/smbd/smb2_getinfo.c +++ b/source3/smbd/smb2_getinfo.c @@ -159,7 +159,10 @@ static void smbd_smb2_request_getinfo_done(struct tevent_req *subreq) return; } - if (!NT_STATUS_IS_OK(call_status)) { + /* some GetInfo responses set STATUS_BUFFER_OVERFLOW and return partial, + but valid data */ + if (!(NT_STATUS_IS_OK(call_status) || + NT_STATUS_EQUAL(call_status, STATUS_BUFFER_OVERFLOW))) { /* Return a specific error with data. */ error = smbd_smb2_request_error_ex(req, call_status, @@ -194,7 +197,7 @@ static void smbd_smb2_request_getinfo_done(struct tevent_req *subreq) outdyn = out_output_buffer; - error = smbd_smb2_request_done(req, outbody, &outdyn); + error = smbd_smb2_request_done_ex(req, call_status, outbody, &outdyn, __location__); if (!NT_STATUS_IS_OK(error)) { smbd_server_connection_terminate(req->sconn, nt_errstr(error)); @@ -416,7 +419,10 @@ static struct tevent_req *smbd_smb2_getinfo_send(TALLOC_CTX *mem_ctx, fsp->fsp_name, &data, &data_size); - if (!NT_STATUS_IS_OK(status)) { + /* some responses set STATUS_BUFFER_OVERFLOW and return + partial, but valid data */ + if (!(NT_STATUS_IS_OK(status) || + NT_STATUS_EQUAL(status, STATUS_BUFFER_OVERFLOW))) { SAFE_FREE(data); if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_LEVEL)) { status = NT_STATUS_INVALID_INFO_CLASS; @@ -503,6 +509,7 @@ static struct tevent_req *smbd_smb2_getinfo_send(TALLOC_CTX *mem_ctx, return tevent_req_post(req, ev); } + state->status = status; tevent_req_done(req); return tevent_req_post(req, ev); } -- 1.7.1 From e8d0fa8c82df0bd4a2f12e869b5f5031244f0cac Mon Sep 17 00:00:00 2001 From: Ralph Wuerthner Date: Fri, 5 Jul 2013 11:32:27 +0200 Subject: [PATCH 3/5] s3:smbd: allow status code in smbd_do_qfsinfo() to be set by information class handler --- source3/smbd/trans2.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index c129946..06591ff 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -3073,6 +3073,7 @@ NTSTATUS smbd_do_qfsinfo(connection_struct *conn, uint32 additional_flags = 0; struct smb_filename smb_fname; SMB_STRUCT_STAT st; + NTSTATUS status = NT_STATUS_OK; if (fname == NULL || fname->base_name == NULL) { filename = "."; @@ -3604,7 +3605,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned } *ret_data_len = data_len; - return NT_STATUS_OK; + return status; } /**************************************************************************** -- 1.7.1 From 101c4a438a6a215dd3ed32afb989a6771af335e1 Mon Sep 17 00:00:00 2001 From: Ralph Wuerthner Date: Wed, 10 Jul 2013 15:52:06 +0200 Subject: [PATCH 4/5] s3:smbd: allow info class SMB_QUERY_FS_VOLUME_INFO to return partial data --- source3/smbd/trans2.c | 6 ++++++ 1 files changed, 6 insertions(+), 0 deletions(-) diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 06591ff..404979c 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -3234,6 +3234,12 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_ex_dev, (u DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol=%s serv=%s\n", (int)strlen(vname),vname, lp_servicename(talloc_tos(), snum))); + if (max_data_bytes >= 24 && data_len > max_data_bytes) { + /* the client only requested a portion of the + volume label */ + data_len = max_data_bytes; + status = STATUS_BUFFER_OVERFLOW; + } break; case SMB_QUERY_FS_SIZE_INFO: -- 1.7.1 From a326beb96bfde1069b689ab42879889b09628ebb Mon Sep 17 00:00:00 2001 From: Ralph Wuerthner Date: Wed, 10 Jul 2013 16:43:39 +0200 Subject: [PATCH 5/5] s3:smbd: allow info class SMB_QUERY_FS_ATTRIBUTE_INFO to return partial data --- source3/smbd/trans2.c | 6 ++++++ 1 files changed, 6 insertions(+), 0 deletions(-) diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 404979c..53a8172 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -3204,6 +3204,12 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_ex_dev, (u STR_UNICODE); SIVAL(pdata,8,len); data_len = 12 + len; + if (max_data_bytes >= 16 && data_len > max_data_bytes) { + /* the client only requested a portion of the + file system name */ + data_len = max_data_bytes; + status = STATUS_BUFFER_OVERFLOW; + } break; case SMB_QUERY_FS_LABEL_INFO: -- 1.7.1