libcli/smb: make smb2cli_ioctl_parse_buffer() available as smb2cli_parse_dyn_buffer()
authorStefan Metzmacher <metze@samba.org>
Tue, 29 Jun 2021 13:24:13 +0000 (15:24 +0200)
committerKarolin Seeger <kseeger@samba.org>
Mon, 19 Jul 2021 06:11:27 +0000 (08:11 +0200)
It will be used in smb2cli_read.c soon...

BUG: https://bugzilla.samba.org/show_bug.cgi?id=14607

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
(cherry picked from commit 1faf15b3d0f41fa8a94b76d1616a4460ce0c6fa4)

libcli/smb/smb2cli_ioctl.c
libcli/smb/smbXcli_base.c
libcli/smb/smbXcli_base.h

index f9abcc57bab39b7d2e69997b63832bfc3d4c765d..d638b28167802a20d9a8b9f52dbb32c7b6c5d0c4 100644 (file)
@@ -160,97 +160,6 @@ struct tevent_req *smb2cli_ioctl_send(TALLOC_CTX *mem_ctx,
        return req;
 }
 
-static NTSTATUS smb2cli_ioctl_parse_buffer(uint32_t dyn_offset,
-                                          const DATA_BLOB dyn_buffer,
-                                          uint32_t min_offset,
-                                          uint32_t buffer_offset,
-                                          uint32_t buffer_length,
-                                          uint32_t max_length,
-                                          uint32_t *next_offset,
-                                          DATA_BLOB *buffer)
-{
-       uint32_t offset;
-       bool oob;
-
-       *buffer = data_blob_null;
-       *next_offset = dyn_offset;
-
-       if (buffer_offset == 0) {
-               /*
-                * If the offset is 0, we better ignore
-                * the buffer_length field.
-                */
-               return NT_STATUS_OK;
-       }
-
-       if (buffer_length == 0) {
-               /*
-                * If the length is 0, we better ignore
-                * the buffer_offset field.
-                */
-               return NT_STATUS_OK;
-       }
-
-       if ((buffer_offset % 8) != 0) {
-               /*
-                * The offset needs to be 8 byte aligned.
-                */
-               return NT_STATUS_INVALID_NETWORK_RESPONSE;
-       }
-
-       /*
-        * We used to enforce buffer_offset to be
-        * an exact match of the expected minimum,
-        * but the NetApp Ontap 7.3.7 SMB server
-        * gets the padding wrong and aligns the
-        * input_buffer_offset by a value of 8.
-        *
-        * So we just enforce that the offset is
-        * not lower than the expected value.
-        */
-       SMB_ASSERT(min_offset >= dyn_offset);
-       if (buffer_offset < min_offset) {
-               return NT_STATUS_INVALID_NETWORK_RESPONSE;
-       }
-
-       /*
-        * Make [input|output]_buffer_offset relative to "dyn_buffer"
-        */
-       offset = buffer_offset - dyn_offset;
-       oob = smb_buffer_oob(dyn_buffer.length, offset, buffer_length);
-       if (oob) {
-               return NT_STATUS_INVALID_NETWORK_RESPONSE;
-       }
-
-       /*
-        * Give the caller a hint what we consumed,
-        * the caller may need to add possible padding.
-        */
-       *next_offset = buffer_offset + buffer_length;
-
-       if (max_length == 0) {
-               /*
-                * If max_input_length is 0 we ignore the
-                * input_buffer_length, because Windows 2008 echos the
-                * DCERPC request from the requested input_buffer to
-                * the response input_buffer.
-                *
-                * We just use the same logic also for max_output_length...
-                */
-               buffer_length = 0;
-       }
-
-       if (buffer_length > max_length) {
-               return NT_STATUS_INVALID_NETWORK_RESPONSE;
-       }
-
-       *buffer = (DATA_BLOB) {
-               .data = dyn_buffer.data + offset,
-               .length = buffer_length,
-       };
-       return NT_STATUS_OK;
-}
-
 static void smb2cli_ioctl_done(struct tevent_req *subreq)
 {
        struct tevent_req *req =
@@ -352,14 +261,14 @@ static void smb2cli_ioctl_done(struct tevent_req *subreq)
 
        input_min_offset = dyn_ofs;
        input_next_offset = dyn_ofs;
-       error = smb2cli_ioctl_parse_buffer(dyn_ofs,
-                                          dyn_buffer,
-                                          input_min_offset,
-                                          input_buffer_offset,
-                                          input_buffer_length,
-                                          state->max_input_length,
-                                          &input_next_offset,
-                                          &state->out_input_buffer);
+       error = smb2cli_parse_dyn_buffer(dyn_ofs,
+                                        dyn_buffer,
+                                        input_min_offset,
+                                        input_buffer_offset,
+                                        input_buffer_length,
+                                        state->max_input_length,
+                                        &input_next_offset,
+                                        &state->out_input_buffer);
        if (tevent_req_nterror(req, error)) {
                return;
        }
@@ -370,14 +279,14 @@ static void smb2cli_ioctl_done(struct tevent_req *subreq)
         */
        output_min_offset = NDR_ROUND(input_next_offset, 8);
        output_next_offset = 0; /* this variable is completely ignored */
-       error = smb2cli_ioctl_parse_buffer(dyn_ofs,
-                                          dyn_buffer,
-                                          output_min_offset,
-                                          output_buffer_offset,
-                                          output_buffer_length,
-                                          state->max_output_length,
-                                          &output_next_offset,
-                                          &state->out_output_buffer);
+       error = smb2cli_parse_dyn_buffer(dyn_ofs,
+                                        dyn_buffer,
+                                        output_min_offset,
+                                        output_buffer_offset,
+                                        output_buffer_length,
+                                        state->max_output_length,
+                                        &output_next_offset,
+                                        &state->out_output_buffer);
        if (tevent_req_nterror(req, error)) {
                return;
        }
index 4909797543c14ba329586f52979c5be8710918d6..bcb601dde59cc52dc654cf1ace3b8673738c6849 100644 (file)
@@ -6664,3 +6664,94 @@ uint64_t smb2cli_conn_get_mid(struct smbXcli_conn *conn)
 {
        return conn->smb2.mid;
 }
+
+NTSTATUS smb2cli_parse_dyn_buffer(uint32_t dyn_offset,
+                                 const DATA_BLOB dyn_buffer,
+                                 uint32_t min_offset,
+                                 uint32_t buffer_offset,
+                                 uint32_t buffer_length,
+                                 uint32_t max_length,
+                                 uint32_t *next_offset,
+                                 DATA_BLOB *buffer)
+{
+       uint32_t offset;
+       bool oob;
+
+       *buffer = data_blob_null;
+       *next_offset = dyn_offset;
+
+       if (buffer_offset == 0) {
+               /*
+                * If the offset is 0, we better ignore
+                * the buffer_length field.
+                */
+               return NT_STATUS_OK;
+       }
+
+       if (buffer_length == 0) {
+               /*
+                * If the length is 0, we better ignore
+                * the buffer_offset field.
+                */
+               return NT_STATUS_OK;
+       }
+
+       if ((buffer_offset % 8) != 0) {
+               /*
+                * The offset needs to be 8 byte aligned.
+                */
+               return NT_STATUS_INVALID_NETWORK_RESPONSE;
+       }
+
+       /*
+        * We used to enforce buffer_offset to be
+        * an exact match of the expected minimum,
+        * but the NetApp Ontap 7.3.7 SMB server
+        * gets the padding wrong and aligns the
+        * input_buffer_offset by a value of 8.
+        *
+        * So we just enforce that the offset is
+        * not lower than the expected value.
+        */
+       SMB_ASSERT(min_offset >= dyn_offset);
+       if (buffer_offset < min_offset) {
+               return NT_STATUS_INVALID_NETWORK_RESPONSE;
+       }
+
+       /*
+        * Make [input|output]_buffer_offset relative to "dyn_buffer"
+        */
+       offset = buffer_offset - dyn_offset;
+       oob = smb_buffer_oob(dyn_buffer.length, offset, buffer_length);
+       if (oob) {
+               return NT_STATUS_INVALID_NETWORK_RESPONSE;
+       }
+
+       /*
+        * Give the caller a hint what we consumed,
+        * the caller may need to add possible padding.
+        */
+       *next_offset = buffer_offset + buffer_length;
+
+       if (max_length == 0) {
+               /*
+                * If max_input_length is 0 we ignore the
+                * input_buffer_length, because Windows 2008 echos the
+                * DCERPC request from the requested input_buffer to
+                * the response input_buffer.
+                *
+                * We just use the same logic also for max_output_length...
+                */
+               buffer_length = 0;
+       }
+
+       if (buffer_length > max_length) {
+               return NT_STATUS_INVALID_NETWORK_RESPONSE;
+       }
+
+       *buffer = (DATA_BLOB) {
+               .data = dyn_buffer.data + offset,
+               .length = buffer_length,
+       };
+       return NT_STATUS_OK;
+}
index 2afc7165cd97942f3df3e11fa954715f51f37408..4452cd808ea1b0a13f26f3faed18dda7f366c6ee 100644 (file)
@@ -390,6 +390,15 @@ void smb2cli_conn_set_cc_max_chunks(struct smbXcli_conn *conn,
 void smb2cli_conn_set_mid(struct smbXcli_conn *conn, uint64_t mid);
 uint64_t smb2cli_conn_get_mid(struct smbXcli_conn *conn);
 
+NTSTATUS smb2cli_parse_dyn_buffer(uint32_t dyn_offset,
+                                 const DATA_BLOB dyn_buffer,
+                                 uint32_t min_offset,
+                                 uint32_t buffer_offset,
+                                 uint32_t buffer_length,
+                                 uint32_t max_length,
+                                 uint32_t *next_offset,
+                                 DATA_BLOB *buffer);
+
 struct tevent_req *smb2cli_req_create(TALLOC_CTX *mem_ctx,
                                      struct tevent_context *ev,
                                      struct smbXcli_conn *conn,