]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
s3:smbd: make sure we pad compounded SMB2 responses to 8 bytes
authorStefan Metzmacher <metze@samba.org>
Tue, 9 Jun 2009 17:21:26 +0000 (19:21 +0200)
committerStefan Metzmacher <metze@samba.org>
Tue, 9 Jun 2009 17:51:02 +0000 (19:51 +0200)
metze

source3/smbd/smb2_server.c

index fa91e29b5ed7c4f6bd81efd4f876aacb9ce69715..84a82ff2419b10968e79b53790c4306837db2ed9 100644 (file)
@@ -751,9 +751,54 @@ NTSTATUS smbd_smb2_request_done_ex(struct smbd_smb2_request *req,
                next_command_ofs += req->out.vector[i+2].iov_len;
        }
 
-       /* TODO: we need to add padding ... */
        if ((next_command_ofs % 8) != 0) {
-               return smbd_smb2_request_error(req, NT_STATUS_INTERNAL_ERROR);
+               size_t pad_size = 8 - (next_command_ofs % 8);
+               if (req->out.vector[i+2].iov_len == 0) {
+                       /*
+                        * if the dyn buffer is empty
+                        * we can use it to add padding
+                        */
+                       uint8_t *pad;
+
+                       pad = talloc_zero_array(req->out.vector,
+                                               uint8_t, pad_size);
+                       if (pad == NULL) {
+                               return smbd_smb2_request_error(req,
+                                               NT_STATUS_NO_MEMORY);
+                       }
+
+                       req->out.vector[i+2].iov_base = (void *)pad;
+                       req->out.vector[i+2].iov_len = pad_size;
+               } else {
+                       /*
+                        * For now we copy the dynamic buffer
+                        * and add the padding to the new buffer
+                        */
+                       size_t old_size;
+                       uint8_t *old_dyn;
+                       size_t new_size;
+                       uint8_t *new_dyn;
+
+                       old_size = req->out.vector[i+2].iov_len;
+                       old_dyn = (uint8_t *)req->out.vector[i+2].iov_base;
+
+                       new_size = old_size + pad_size;
+                       new_dyn = talloc_array(req->out.vector,
+                                              uint8_t, new_size);
+                       if (new_dyn == NULL) {
+                               return smbd_smb2_request_error(req,
+                                               NT_STATUS_NO_MEMORY);
+                       }
+
+                       memcpy(new_dyn, old_dyn, old_size);
+                       memset(new_dyn + old_size, 0, pad_size);
+
+                       req->out.vector[i+2].iov_base = (void *)new_dyn;
+                       req->out.vector[i+2].iov_len = new_size;
+
+                       TALLOC_FREE(old_dyn);
+               }
+               next_command_ofs += pad_size;
        }
 
        SIVAL(outhdr, SMB2_HDR_NEXT_COMMAND, next_command_ofs);