Print this page
NEX-5665 SMB2 oplock leases
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
NEX-5665 SMB2 oplock leases
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Roman Strashkin <roman.strashkin@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-4538 SMB1 create file should support extended_response format (2)
NEX-6116 Failures in smbtorture raw.open
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Kevin Crowe <kevin.crowe@nexenta.com>
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Include this commit if upstreaming/backporting any of:
NEX-4540 SMB server declines EA support incorrectly
NEX-4239 smbtorture create failures re. allocation size
(illumos) 6398 SMB should support path names longer than 1024
NEX-4538 SMB1 create file should support extended_response format
Reviewed by: Matt Barden <Matt.Barden@nexenta.com>
Reviewed by: Bayard Bell <bayard.bell@nexenta.com>
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)
SMB-50 User-mode SMB server
 Includes work by these authors:
 Thomas Keiser <thomas.keiser@nexenta.com>
 Albert Lee <trisk@nexenta.com>
SMB-63 taskq_create_proc ... TQ_DYNAMIC puts tasks in p0
re #11974 CIFS Share - Tree connect fails from Windows 7 Clients
re #14152 Race between ipmi_submit_driver_request() and kcs_loop() (sync with illumos fix 3902)
SMB-46 File handle leaks exposed by mtime fixes (rm 7815)
re #7815 SMB server delivers old modification time...

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/fs/smbsrv/smb_nt_transact_create.c
          +++ new/usr/src/uts/common/fs/smbsrv/smb_nt_transact_create.c
↓ open down ↓ 12 lines elided ↑ open up ↑
  13   13   * When distributing Covered Code, include this CDDL HEADER in each
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  /*
  22   22   * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  23      - * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
       23 + * Copyright 2017 Nexenta Systems, Inc.  All rights reserved.
  24   24   */
  25   25  
  26   26  /*
  27   27   * This command is used to create or open a file or directory, when EAs
  28   28   * or an SD must be applied to the file. The functionality is similar
  29   29   * to SmbNtCreateAndx with the option to supply extended attributes or
  30   30   * a security descriptor.
  31   31   *
  32   32   * Note: we don't decode the extended attributes because we don't
  33   33   * support them at this time.
  34   34   */
  35   35  
  36   36  #include <smbsrv/smb_kproto.h>
  37   37  #include <smbsrv/smb_fsops.h>
  38   38  
       39 +extern int smb_nt_create_enable_extended_response;
       40 +
  39   41  /*
  40   42   * smb_nt_transact_create
  41   43   *
  42   44   * This command is used to create or open a file or directory, when EAs
  43   45   * or an SD must be applied to the file. The request parameter block
  44   46   * encoding, data block encoding and output parameter block encoding are
  45   47   * described in CIFS section 4.2.2.
  46   48   *
  47   49   * The format of the command is SmbNtTransact but it is basically the same
  48   50   * as SmbNtCreateAndx with the option to supply extended attributes or a
↓ open down ↓ 27 lines elided ↑ open up ↑
  76   78              &op->create_options,
  77   79              &sd_len,
  78   80              &EaLength,
  79   81              &NameLength,
  80   82              &ImpersonationLevel,
  81   83              &SecurityFlags);
  82   84  
  83   85          if (rc == 0) {
  84   86                  if (NameLength == 0) {
  85   87                          op->fqi.fq_path.pn_path = "\\";
  86      -                } else if (NameLength >= MAXPATHLEN) {
  87      -                        smbsr_error(sr, NT_STATUS_OBJECT_PATH_NOT_FOUND,
  88      -                            ERRDOS, ERROR_PATH_NOT_FOUND);
       88 +                } else if (NameLength >= SMB_MAXPATHLEN) {
       89 +                        smbsr_error(sr, NT_STATUS_OBJECT_NAME_INVALID,
       90 +                            ERRDOS, ERROR_INVALID_NAME);
  89   91                          rc = -1;
  90   92                  } else {
  91   93                          rc = smb_mbc_decodef(&xa->req_param_mb, "%#u",
  92   94                              sr, NameLength, &op->fqi.fq_path.pn_path);
  93   95                  }
  94   96          }
  95   97  
  96   98          op->op_oplock_level = SMB_OPLOCK_NONE;
  97   99          if (op->nt_flags & NT_CREATE_FLAG_REQUEST_OPLOCK) {
  98  100                  if (op->nt_flags & NT_CREATE_FLAG_REQUEST_OPBATCH)
↓ open down ↓ 7 lines elided ↑ open up ↑
 106  108                  if (status != NT_STATUS_SUCCESS) {
 107  109                          smbsr_error(sr, status, 0, 0);
 108  110                          return (SDRC_ERROR);
 109  111                  }
 110  112                  op->sd = kmem_alloc(sizeof (smb_sd_t), KM_SLEEP);
 111  113                  *op->sd = sd;
 112  114          } else {
 113  115                  op->sd = NULL;
 114  116          }
 115  117  
 116      -        DTRACE_SMB_2(op__NtTransactCreate__start, smb_request_t *, sr,
 117      -            struct open_param *, op);
      118 +        DTRACE_SMB_START(op__NtTransactCreate, smb_request_t *, sr);
 118  119  
 119  120          return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
 120  121  }
 121  122  
 122  123  void
 123  124  smb_post_nt_transact_create(smb_request_t *sr, smb_xa_t *xa)
 124  125  {
 125  126          smb_sd_t *sd = sr->arg.open.sd;
      127 +        _NOTE(ARGUNUSED(xa))
 126  128  
 127      -        DTRACE_SMB_2(op__NtTransactCreate__done, smb_request_t *, sr,
 128      -            smb_xa_t *, xa);
      129 +        DTRACE_SMB_DONE(op__NtTransactCreate, smb_request_t *, sr);
 129  130  
 130  131          if (sd) {
 131  132                  smb_sd_term(sd);
 132  133                  kmem_free(sd, sizeof (smb_sd_t));
 133  134          }
 134  135  
 135      -        if (sr->arg.open.dir != NULL)
      136 +        if (sr->arg.open.dir != NULL) {
 136  137                  smb_ofile_release(sr->arg.open.dir);
      138 +                sr->arg.open.dir = NULL;
      139 +        }
 137  140  }
 138  141  
      142 +/*
      143 + * A lot like smb_com_nt_create_andx
      144 + */
 139  145  smb_sdrc_t
 140  146  smb_nt_transact_create(smb_request_t *sr, smb_xa_t *xa)
 141  147  {
 142      -        struct open_param *op = &sr->arg.open;
 143      -        uint8_t                 DirFlag;
 144      -        smb_attr_t              attr;
      148 +        struct open_param       *op = &sr->arg.open;
      149 +        smb_attr_t              *ap = &op->fqi.fq_fattr;
 145  150          smb_ofile_t             *of;
 146      -        uint32_t                status;
 147  151          int                     rc;
      152 +        uint8_t                 DirFlag;
      153 +        uint32_t                status;
 148  154  
      155 +        if (op->create_options & ~SMB_NTCREATE_VALID_OPTIONS) {
      156 +                smbsr_error(sr, NT_STATUS_INVALID_PARAMETER,
      157 +                    ERRDOS, ERROR_INVALID_PARAMETER);
      158 +                return (SDRC_ERROR);
      159 +        }
      160 +
      161 +        if (op->create_options & FILE_OPEN_BY_FILE_ID) {
      162 +                smbsr_error(sr, NT_STATUS_NOT_SUPPORTED,
      163 +                    ERRDOS, ERROR_NOT_SUPPORTED);
      164 +                return (SDRC_ERROR);
      165 +        }
      166 +
 149  167          if ((op->create_options & FILE_DELETE_ON_CLOSE) &&
 150  168              !(op->desired_access & DELETE)) {
 151  169                  smbsr_error(sr, NT_STATUS_INVALID_PARAMETER,
 152  170                      ERRDOS, ERRbadaccess);
 153  171                  return (SDRC_ERROR);
 154  172          }
 155  173  
 156  174          if (op->create_disposition > FILE_MAXIMUM_DISPOSITION) {
 157  175                  smbsr_error(sr, NT_STATUS_INVALID_PARAMETER,
 158  176                      ERRDOS, ERRbadaccess);
↓ open down ↓ 17 lines elided ↑ open up ↑
 176  194          } else {
 177  195                  op->dir = smb_ofile_lookup_by_fid(sr, (uint16_t)op->rootdirfid);
 178  196                  if (op->dir == NULL) {
 179  197                          smbsr_error(sr, NT_STATUS_INVALID_HANDLE,
 180  198                              ERRDOS, ERRbadfid);
 181  199                          return (SDRC_ERROR);
 182  200                  }
 183  201                  op->fqi.fq_dnode = op->dir->f_node;
 184  202          }
 185  203  
 186      -        op->op_oplock_levelII = B_TRUE;
 187      -
 188  204          status = smb_common_open(sr);
 189  205          if (status != NT_STATUS_SUCCESS) {
 190  206                  smbsr_status(sr, status, 0, 0);
 191  207                  return (SDRC_ERROR);
 192  208          }
      209 +        if (op->op_oplock_level != SMB_OPLOCK_NONE) {
      210 +                /* Oplock req. in op->op_oplock_level etc. */
      211 +                smb1_oplock_acquire(sr, B_TRUE);
      212 +        }
 193  213  
 194  214          /*
 195  215           * NB: after the above smb_common_open() success,
 196  216           * we have a handle allocated (sr->fid_ofile).
 197  217           * If we don't return success, we must close it.
 198  218           */
 199  219          of = sr->fid_ofile;
 200  220  
 201  221          switch (sr->tid_tree->t_res_type & STYPE_MASK) {
 202  222          case STYPE_DISKTREE:
 203  223          case STYPE_PRINTQ:
 204  224                  if (op->create_options & FILE_DELETE_ON_CLOSE)
 205      -                        smb_ofile_set_delete_on_close(of);
 206      -
      225 +                        smb_ofile_set_delete_on_close(sr, of);
 207  226                  DirFlag = smb_node_is_dir(of->f_node) ? 1 : 0;
 208      -                bzero(&attr, sizeof (attr));
 209      -                attr.sa_mask = SMB_AT_ALL;
 210      -                rc = smb_node_getattr(sr, of->f_node, of->f_cr, of, &attr);
 211      -                if (rc != 0) {
 212      -                        smbsr_errno(sr, rc);
 213      -                        goto errout;
 214      -                }
 215      -
 216      -                rc = smb_mbc_encodef(&xa->rep_param_mb, "b.wllTTTTlqqwwb",
 217      -                    op->op_oplock_level,
 218      -                    sr->smb_fid,
 219      -                    op->action_taken,
 220      -                    0,  /* EaErrorOffset */
 221      -                    &attr.sa_crtime,
 222      -                    &attr.sa_vattr.va_atime,
 223      -                    &attr.sa_vattr.va_mtime,
 224      -                    &attr.sa_vattr.va_ctime,
 225      -                    op->dattr & FILE_ATTRIBUTE_MASK,
 226      -                    attr.sa_allocsz,
 227      -                    attr.sa_vattr.va_size,
 228      -                    op->ftype,
 229      -                    op->devstate,
 230      -                    DirFlag);
 231  227                  break;
 232  228  
 233  229          case STYPE_IPC:
 234      -                bzero(&attr, sizeof (smb_attr_t));
 235      -                rc = smb_mbc_encodef(&xa->rep_param_mb, "b.wllTTTTlqqwwb",
 236      -                    0,
 237      -                    sr->smb_fid,
 238      -                    op->action_taken,
 239      -                    0,  /* EaErrorOffset */
 240      -                    &attr.sa_crtime,
 241      -                    &attr.sa_vattr.va_atime,
 242      -                    &attr.sa_vattr.va_mtime,
 243      -                    &attr.sa_vattr.va_ctime,
 244      -                    op->dattr,
 245      -                    0x1000LL,
 246      -                    0LL,
 247      -                    op->ftype,
 248      -                    op->devstate,
 249      -                    0);
      230 +                DirFlag = 0;
 250  231                  break;
 251  232  
 252  233          default:
 253  234                  smbsr_error(sr, NT_STATUS_INVALID_DEVICE_REQUEST,
 254  235                      ERRDOS, ERROR_INVALID_FUNCTION);
 255  236                  goto errout;
 256  237          }
 257      -        return (SDRC_SUCCESS);
 258  238  
      239 +        if ((op->nt_flags & NT_CREATE_FLAG_EXTENDED_RESPONSE) != 0 &&
      240 +            smb_nt_create_enable_extended_response != 0) {
      241 +                uint32_t MaxAccess = 0;
      242 +                if (of->f_node != NULL) {
      243 +                        smb_fsop_eaccess(sr, of->f_cr, of->f_node, &MaxAccess);
      244 +                }
      245 +                MaxAccess |= of->f_granted_access;
      246 +
      247 +                rc = smb_mbc_encodef(
      248 +                    &xa->rep_param_mb, "bbwllTTTTlqqwwb16.qll",
      249 +                    op->op_oplock_level,        /* (b) */
      250 +                    1,          /* ResponseType    (b) */
      251 +                    sr->smb_fid,                /* (w) */
      252 +                    op->action_taken,           /* (l) */
      253 +                    0,          /* EaErrorOffset   (l) */
      254 +                    &ap->sa_crtime,             /* (T) */
      255 +                    &ap->sa_vattr.va_atime,     /* (T) */
      256 +                    &ap->sa_vattr.va_mtime,     /* (T) */
      257 +                    &ap->sa_vattr.va_ctime,     /* (T) */
      258 +                    op->dattr & FILE_ATTRIBUTE_MASK, /* (l) */
      259 +                    ap->sa_allocsz,             /* (q) */
      260 +                    ap->sa_vattr.va_size,       /* (q) */
      261 +                    op->ftype,                  /* (w) */
      262 +                    op->devstate,               /* (w) */
      263 +                    DirFlag,                    /* (b) */
      264 +                    /* volume guid                (16.) */
      265 +                    op->fileid,                 /* (q) */
      266 +                    MaxAccess,                  /* (l) */
      267 +                    0);         /* guest access    (l) */
      268 +        } else {
      269 +                rc = smb_mbc_encodef(
      270 +                    &xa->rep_param_mb, "bbwllTTTTlqqwwb",
      271 +                    op->op_oplock_level,        /* (b) */
      272 +                    0,          /* ResponseType    (b) */
      273 +                    sr->smb_fid,                /* (w) */
      274 +                    op->action_taken,           /* (l) */
      275 +                    0,          /* EaErrorOffset   (l) */
      276 +                    &ap->sa_crtime,             /* (T) */
      277 +                    &ap->sa_vattr.va_atime,     /* (T) */
      278 +                    &ap->sa_vattr.va_mtime,     /* (T) */
      279 +                    &ap->sa_vattr.va_ctime,     /* (T) */
      280 +                    op->dattr & FILE_ATTRIBUTE_MASK, /* (l) */
      281 +                    ap->sa_allocsz,             /* (q) */
      282 +                    ap->sa_vattr.va_size,       /* (q) */
      283 +                    op->ftype,                  /* (w) */
      284 +                    op->devstate,               /* (w) */
      285 +                    DirFlag);                   /* (b) */
      286 +        }
      287 +
      288 +        if (rc == 0)
      289 +                return (SDRC_SUCCESS);
      290 +
 259  291  errout:
 260  292          smb_ofile_close(of, 0);
 261  293          return (SDRC_ERROR);
 262  294  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX