Print this page
NEX-17289 Minimal SMB 3.0.2 support
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-1643 dtrace provider for smbsrv
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Matt Barden <matt.barden@nexenta.com>
NEX-5844 want SMB2 ioctl FSCTL_SRV_COPYCHUNK
NEX-6124 smb_fsop_read/write should allow file != sr->fid_ofile
NEX-6125 smbtorture invalid response with smb2.ioctl
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Matt Barden <matt.barden@nexenta.com>
NEX-3662 Backport illumos 1501: taskq_create_proc ... TQ_DYNAMIC puts tasks in p0 (take 2)
Reviewed by: Garrett D'Amore <garrett@damore.org>
Reviewed by: Dan McDonald <danmcd@omniti.com>
Reviewed by: Robert Mustacchi <rm@joyent.com>
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Marcel Telka <marcel.telka@nexenta.com>
NEX-3576 RPC error when displaying open files via Windows MMC
Reviewed by: Kevin Crowe <kevin.crowe@nexenta.com>
NEX-2188 Browsing top level share produces RPC error 1728
SMB-122 smbd core dumps in smbd_dc_update / smb_log
SMB-117 Win7 fails to open security properties
SMB-11 SMB2 message parse & dispatch
SMB-12 SMB2 Negotiate Protocol
SMB-13 SMB2 Session Setup
SMB-14 SMB2 Logoff
SMB-15 SMB2 Tree Connect
SMB-16 SMB2 Tree Disconnect
SMB-17 SMB2 Create
SMB-18 SMB2 Close
SMB-19 SMB2 Flush
SMB-20 SMB2 Read
SMB-21 SMB2 Write
SMB-22 SMB2 Lock/Unlock
SMB-23 SMB2 Ioctl
SMB-24 SMB2 Cancel
SMB-25 SMB2 Echo
SMB-26 SMB2 Query Dir
SMB-27 SMB2 Change Notify
SMB-28 SMB2 Query Info
SMB-29 SMB2 Set Info
SMB-30 SMB2 Oplocks
SMB-53 SMB2 Create Context options
(SMB2 code review cleanup 1, 2, 3)
   1 /*
   2  * This file and its contents are supplied under the terms of the
   3  * Common Development and Distribution License ("CDDL"), version 1.0.
   4  * You may only use this file in accordance with the terms of version
   5  * 1.0 of the CDDL.
   6  *
   7  * A full copy of the text of the CDDL should have accompanied this
   8  * source.  A copy of the CDDL is also available via the Internet at
   9  * http://www.illumos.org/license/CDDL.
  10  */
  11 
  12 /*
  13  * Copyright 2015 Nexenta Systems, Inc.  All rights reserved.
  14  */
  15 
  16 /*
  17  * Dispatch function for SMB2_READ
  18  */
  19 
  20 #include <smbsrv/smb2_kproto.h>
  21 #include <smbsrv/smb_fsops.h>
  22 


  23 smb_sdrc_t
  24 smb2_read(smb_request_t *sr)
  25 {
  26         smb_ofile_t *of = NULL;
  27         smb_vdb_t *vdb = NULL;
  28         struct mbuf *m = NULL;
  29         uint16_t StructSize;
  30         uint8_t Padding;

  31         uint8_t DataOff;
  32         uint32_t Length;
  33         uint64_t Offset;
  34         smb2fid_t smb2fid;
  35         uint32_t MinCount;
  36         uint32_t Channel;
  37         uint32_t Remaining;
  38         uint16_t ChanInfoOffset;
  39         uint16_t ChanInfoLength;
  40         uint32_t XferCount;
  41         uint32_t status;
  42         int rc = 0;


  43 
  44         /*
  45          * SMB2 Read request
  46          */
  47         rc = smb_mbc_decodef(
  48             &sr->smb_data,
  49             "wb.lqqqlllww",
  50             &StructSize,            /* w */
  51             &Padding,                       /* b. */

  52             &Length,                        /* l */
  53             &Offset,                        /* q */
  54             &smb2fid.persistent,    /* q */
  55             &smb2fid.temporal,              /* q */
  56             &MinCount,                      /* l */
  57             &Channel,                       /* l */
  58             &Remaining,                     /* l */
  59             &ChanInfoOffset,                /* w */
  60             &ChanInfoLength);               /* w */
  61         if (rc)
  62                 return (SDRC_ERROR);
  63         if (StructSize != 49)
  64                 return (SDRC_ERROR);
  65 



  66         status = smb2sr_lookup_fid(sr, &smb2fid);
  67         if (status) {
  68                 smb2sr_put_error(sr, status);
  69                 return (SDRC_SUCCESS);
  70         }
  71         of = sr->fid_ofile;
  72 





  73         if (Length > smb2_max_rwsize) {
  74                 smb2sr_put_error(sr, NT_STATUS_INVALID_PARAMETER);
  75                 return (SDRC_SUCCESS);
  76         }
  77         if (MinCount > Length)
  78                 MinCount = Length;
  79 
  80         /* This is automatically free'd. */
  81         vdb = smb_srm_zalloc(sr, sizeof (*vdb));
  82         vdb->vdb_tag = 0;
  83         vdb->vdb_uio.uio_iov = &vdb->vdb_iovec[0];
  84         vdb->vdb_uio.uio_iovcnt = MAX_IOVEC;
  85         vdb->vdb_uio.uio_resid = Length;
  86         vdb->vdb_uio.uio_loffset = (offset_t)Offset;
  87         vdb->vdb_uio.uio_segflg = UIO_SYSSPACE;
  88         vdb->vdb_uio.uio_extflg = UIO_COPY_DEFAULT;
  89 
  90         sr->raw_data.max_bytes = Length;
  91         m = smb_mbuf_allocate(&vdb->vdb_uio);
  92 















  93         switch (of->f_tree->t_res_type & STYPE_MASK) {
  94         case STYPE_DISKTREE:
  95                 if (!smb_node_is_dir(of->f_node)) {
  96                         /* Check for conflicting locks. */
  97                         rc = smb_lock_range_access(sr, of->f_node,
  98                             Offset, Length, B_FALSE);
  99                         if (rc) {
 100                                 rc = ERANGE;
 101                                 break;
 102                         }
 103                 }
 104                 rc = smb_fsop_read(sr, of->f_cr, of->f_node, &vdb->vdb_uio);

 105                 break;
 106         case STYPE_IPC:



 107                 rc = smb_opipe_read(sr, &vdb->vdb_uio);
 108                 break;
 109         default:
 110         case STYPE_PRINTQ:
 111                 rc = EACCES;
 112                 break;
 113         }

 114 
 115         /* How much data we moved. */
 116         XferCount = Length - vdb->vdb_uio.uio_resid;
 117 
 118         sr->raw_data.max_bytes = XferCount;
 119         smb_mbuf_trim(m, XferCount);
 120         MBC_ATTACH_MBUF(&sr->raw_data, m);
 121 
 122         /*
 123          * Checking the error return _after_ dealing with
 124          * the returned data so that if m was allocated,
 125          * it will be free'd via sr->raw_data cleanup.
 126          */
 127         if (rc) {
 128                 smb2sr_put_errno(sr, rc);



 129                 return (SDRC_SUCCESS);
 130         }
 131 
 132         /*
 133          * SMB2 Read reply
 134          */
 135         DataOff = SMB2_HDR_SIZE + 16;
 136         rc = smb_mbc_encodef(
 137             &sr->reply,
 138             "wb.lllC",
 139             17, /* StructSize */        /* w */
 140             DataOff,                    /* b. */
 141             XferCount,                  /* l */
 142             0, /* DataRemaining */      /* l */
 143             0, /* reserved */           /* l */
 144             &sr->raw_data);              /* C */
 145         if (rc)

 146                 return (SDRC_ERROR);

 147 
 148         mutex_enter(&of->f_mutex);
 149         of->f_seek_pos = Offset + XferCount;
 150         mutex_exit(&of->f_mutex);
 151 
 152         return (SDRC_SUCCESS);
 153 }
   1 /*
   2  * This file and its contents are supplied under the terms of the
   3  * Common Development and Distribution License ("CDDL"), version 1.0.
   4  * You may only use this file in accordance with the terms of version
   5  * 1.0 of the CDDL.
   6  *
   7  * A full copy of the text of the CDDL should have accompanied this
   8  * source.  A copy of the CDDL is also available via the Internet at
   9  * http://www.illumos.org/license/CDDL.
  10  */
  11 
  12 /*
  13  * Copyright 2018 Nexenta Systems, Inc.  All rights reserved.
  14  */
  15 
  16 /*
  17  * Dispatch function for SMB2_READ
  18  */
  19 
  20 #include <smbsrv/smb2_kproto.h>
  21 #include <smbsrv/smb_fsops.h>
  22 
  23 extern boolean_t smb_allow_unbuffered;
  24 
  25 smb_sdrc_t
  26 smb2_read(smb_request_t *sr)
  27 {
  28         smb_ofile_t *of = NULL;
  29         smb_vdb_t *vdb = NULL;
  30         struct mbuf *m = NULL;
  31         uint16_t StructSize;
  32         uint8_t Padding;
  33         uint8_t Flags;
  34         uint8_t DataOff;
  35         uint32_t Length;
  36         uint64_t Offset;
  37         smb2fid_t smb2fid;
  38         uint32_t MinCount;
  39         uint32_t Channel;
  40         uint32_t Remaining;
  41         uint16_t ChanInfoOffset;
  42         uint16_t ChanInfoLength;
  43         uint32_t XferCount;
  44         uint32_t status;
  45         int rc = 0;
  46         boolean_t unbuffered = B_FALSE;
  47         int ioflag = 0;
  48 
  49         /*
  50          * SMB2 Read request
  51          */
  52         rc = smb_mbc_decodef(
  53             &sr->smb_data,
  54             "wbblqqqlllww",
  55             &StructSize,            /* w */
  56             &Padding,                       /* b */
  57             &Flags,                 /* b */
  58             &Length,                        /* l */
  59             &Offset,                        /* q */
  60             &smb2fid.persistent,    /* q */
  61             &smb2fid.temporal,              /* q */
  62             &MinCount,                      /* l */
  63             &Channel,                       /* l */
  64             &Remaining,                     /* l */
  65             &ChanInfoOffset,                /* w */
  66             &ChanInfoLength);               /* w */
  67         if (rc)
  68                 return (SDRC_ERROR);
  69         if (StructSize != 49)
  70                 return (SDRC_ERROR);
  71 
  72         /*
  73          * Want FID lookup before the start probe.
  74          */
  75         status = smb2sr_lookup_fid(sr, &smb2fid);




  76         of = sr->fid_ofile;
  77 
  78         DTRACE_SMB2_START(op__Read, smb_request_t *, sr); /* arg.rw */
  79 
  80         if (status)
  81                 goto errout; /* Bad FID */
  82 
  83         if (Length > smb2_max_rwsize) {
  84                 status = NT_STATUS_INVALID_PARAMETER;
  85                 goto errout;
  86         }
  87         if (MinCount > Length)
  88                 MinCount = Length;
  89 
  90         /* This is automatically free'd. */
  91         vdb = smb_srm_zalloc(sr, sizeof (*vdb));
  92         vdb->vdb_tag = 0;
  93         vdb->vdb_uio.uio_iov = &vdb->vdb_iovec[0];
  94         vdb->vdb_uio.uio_iovcnt = MAX_IOVEC;
  95         vdb->vdb_uio.uio_resid = Length;
  96         vdb->vdb_uio.uio_loffset = (offset_t)Offset;
  97         vdb->vdb_uio.uio_segflg = UIO_SYSSPACE;
  98         vdb->vdb_uio.uio_extflg = UIO_COPY_DEFAULT;
  99 
 100         sr->raw_data.max_bytes = Length;
 101         m = smb_mbuf_allocate(&vdb->vdb_uio);
 102 
 103         /*
 104          * Unbuffered refers to the MS-FSA Read argument by the same name.
 105          * It indicates that the cache for this range should be flushed to disk,
 106          * and data read directly from disk, bypassing the cache.
 107          * We don't allow that degree of cache management.
 108          * Translate this directly as FRSYNC,
 109          * which should at least flush the cache first.
 110          */
 111 
 112         if (smb_allow_unbuffered &&
 113             (Flags & SMB2_READFLAG_READ_UNBUFFERED) != 0) {
 114                 unbuffered = B_TRUE;
 115                 ioflag = FRSYNC;
 116         }
 117 
 118         switch (of->f_tree->t_res_type & STYPE_MASK) {
 119         case STYPE_DISKTREE:
 120                 if (!smb_node_is_dir(of->f_node)) {
 121                         /* Check for conflicting locks. */
 122                         rc = smb_lock_range_access(sr, of->f_node,
 123                             Offset, Length, B_FALSE);
 124                         if (rc) {
 125                                 rc = ERANGE;
 126                                 break;
 127                         }
 128                 }
 129                 rc = smb_fsop_read(sr, of->f_cr, of->f_node, of,
 130                     &vdb->vdb_uio, ioflag);
 131                 break;
 132         case STYPE_IPC:
 133                 if (unbuffered)
 134                         rc = EINVAL;
 135                 else
 136                         rc = smb_opipe_read(sr, &vdb->vdb_uio);
 137                 break;
 138         default:
 139         case STYPE_PRINTQ:
 140                 rc = EACCES;
 141                 break;
 142         }
 143         status = smb_errno2status(rc);
 144 
 145         /* How much data we moved. */
 146         XferCount = Length - vdb->vdb_uio.uio_resid;
 147 
 148         sr->raw_data.max_bytes = XferCount;
 149         smb_mbuf_trim(m, XferCount);
 150         MBC_ATTACH_MBUF(&sr->raw_data, m);
 151 
 152         /*
 153          * Checking the error return _after_ dealing with
 154          * the returned data so that if m was allocated,
 155          * it will be free'd via sr->raw_data cleanup.
 156          */
 157 errout:
 158         sr->smb2_status = status;
 159         DTRACE_SMB2_DONE(op__Read, smb_request_t *, sr); /* arg.rw */
 160         if (status) {
 161                 smb2sr_put_error(sr, status);
 162                 return (SDRC_SUCCESS);
 163         }
 164 
 165         /*
 166          * SMB2 Read reply
 167          */
 168         DataOff = SMB2_HDR_SIZE + 16;
 169         rc = smb_mbc_encodef(
 170             &sr->reply,
 171             "wb.lllC",
 172             17, /* StructSize */        /* w */
 173             DataOff,                    /* b. */
 174             XferCount,                  /* l */
 175             0, /* DataRemaining */      /* l */
 176             0, /* reserved */           /* l */
 177             &sr->raw_data);              /* C */
 178         if (rc) {
 179                 sr->smb2_status = NT_STATUS_INTERNAL_ERROR;
 180                 return (SDRC_ERROR);
 181         }
 182 
 183         mutex_enter(&of->f_mutex);
 184         of->f_seek_pos = Offset + XferCount;
 185         mutex_exit(&of->f_mutex);
 186 
 187         return (SDRC_SUCCESS);
 188 }