s3:smb2_ioctl: add some more validation checks
authorStefan Metzmacher <metze@samba.org>
Tue, 29 May 2012 10:06:22 +0000 (12:06 +0200)
committerStefan Metzmacher <metze@samba.org>
Tue, 29 May 2012 15:02:13 +0000 (17:02 +0200)
Based on a patch from Christian Ambach <ambi@samba.org>.

metze

source3/smbd/smb2_ioctl.c

index cd303eddde2cab649e044efa989c93708b5e53ab..521b13119e7c8ed38dfa4a75a807018208e71cbe 100644 (file)
@@ -90,13 +90,42 @@ NTSTATUS smbd_smb2_request_process_ioctl(struct smbd_smb2_request *req)
        in_input_buffer.data = (uint8_t *)req->in.vector[i+2].iov_base;
        in_input_buffer.length = in_input_length;
 
-       if (req->compat_chain_fsp) {
-               /* skip check */
-       } else if (in_file_id_persistent == UINT64_MAX &&
-                  in_file_id_volatile == UINT64_MAX) {
-               /* without a handle */
-       } else if (in_file_id_persistent != in_file_id_volatile) {
-               return smbd_smb2_request_error(req, NT_STATUS_FILE_CLOSED);
+       /*
+        * If the Flags field of the request is not SMB2_0_IOCTL_IS_FSCTL the
+        * server MUST fail the request with STATUS_NOT_SUPPORTED.
+        */
+       if (in_flags != SMB2_IOCTL_FLAG_IS_FSCTL) {
+               return smbd_smb2_request_error(req, NT_STATUS_NOT_SUPPORTED);
+       }
+
+       switch (in_ctl_code) {
+       case FSCTL_DFS_GET_REFERRALS:
+       case FSCTL_DFS_GET_REFERRALS_EX:
+       case FSCTL_PIPE_WAIT:
+       case FSCTL_VALIDATE_NEGOTIATE_INFO_224:
+       case FSCTL_VALIDATE_NEGOTIATE_INFO:
+       case FSCTL_QUERY_NETWORK_INTERFACE_INFO:
+               /*
+                * Some SMB2 specific CtlCodes like FSCTL_DFS_GET_REFERRALS or
+                * FSCTL_PIPE_WAIT does not take a file handle.
+                *
+                * If FileId in the SMB2 Header of the request is not
+                * 0xFFFFFFFFFFFFFFFF, then the server MUST fail the request
+                * with STATUS_INVALID_PARAMETER.
+                */
+               if (in_file_id_persistent != UINT64_MAX ||
+                   in_file_id_volatile != UINT64_MAX) {
+                       return smbd_smb2_request_error(req,
+                               NT_STATUS_INVALID_PARAMETER);
+               }
+               break;
+       default:
+               if (req->compat_chain_fsp) {
+                       /* skip check */
+               } else if (in_file_id_persistent != in_file_id_volatile) {
+                       return smbd_smb2_request_error(req, NT_STATUS_FILE_CLOSED);
+               }
+               break;
        }
 
        subreq = smbd_smb2_ioctl_send(req,