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-14982 smbtorture raw tests fail after NEX-4538
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
corrects:
 NEX-4538 SMB1 create file should support extended_response format
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-4909 SMB1: getting "RPC struct is bad" trying to mkdir on OS X
Reviewed by: Alek Pinchuk <alek.pinchuk@nexenta.com>
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
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-115 Support SMB path names with length > 1024
SMB-100 Internal error if filename is too long
Approved by: Gordon Ross <gwr@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-63 taskq_create_proc ... TQ_DYNAMIC puts tasks in p0
re #11974 CIFS Share - Tree connect fails from Windows 7 Clients
SUS-172 Excel 2003 warning dialog when re-saving a file
SUS-173 Open fails if the client does not ask for read_attribute permission
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_create_andx.c
          +++ new/usr/src/uts/common/fs/smbsrv/smb_nt_create_andx.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 2014 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.
  28   28   */
  29   29  
  30   30  
  31   31  #include <smbsrv/smb_kproto.h>
  32   32  #include <smbsrv/smb_fsops.h>
  33   33  #include <smbsrv/smb_vops.h>
  34   34  
       35 +int smb_nt_create_enable_extended_response = 1;
       36 +
  35   37  /*
  36   38   * smb_com_nt_create_andx
  37   39   *
  38   40   * This command is used to create or open a file or directory.
  39   41   *
  40   42   *  Client Request                     Description
  41   43   *  =================================  ==================================
  42   44   *
  43   45   *  UCHAR WordCount;                   Count of parameter words = 24
  44   46   *  UCHAR AndXCommand;                 Secondary command;  0xFF = None
↓ open down ↓ 158 lines elided ↑ open up ↑
 203  205          }
 204  206  
 205  207          op->op_oplock_level = SMB_OPLOCK_NONE;
 206  208          if (op->nt_flags & NT_CREATE_FLAG_REQUEST_OPLOCK) {
 207  209                  if (op->nt_flags & NT_CREATE_FLAG_REQUEST_OPBATCH)
 208  210                          op->op_oplock_level = SMB_OPLOCK_BATCH;
 209  211                  else
 210  212                          op->op_oplock_level = SMB_OPLOCK_EXCLUSIVE;
 211  213          }
 212  214  
 213      -        DTRACE_SMB_2(op__NtCreateX__start, smb_request_t *, sr,
 214      -            struct open_param *, op);
      215 +        DTRACE_SMB_START(op__NtCreateX, smb_request_t *, sr); /* arg.open */
 215  216  
 216  217          return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
 217  218  }
 218  219  
 219  220  void
 220  221  smb_post_nt_create_andx(smb_request_t *sr)
 221  222  {
 222      -        DTRACE_SMB_1(op__NtCreateX__done, smb_request_t *, sr);
      223 +        DTRACE_SMB_DONE(op__NtCreateX, smb_request_t *, sr);
 223  224  
 224  225          if (sr->arg.open.dir != NULL) {
 225  226                  smb_ofile_release(sr->arg.open.dir);
 226  227                  sr->arg.open.dir = NULL;
 227  228          }
 228  229  }
 229  230  
      231 +/*
      232 + * A lot like smb_nt_transact_create
      233 + */
 230  234  smb_sdrc_t
 231  235  smb_com_nt_create_andx(struct smb_request *sr)
 232  236  {
 233  237          struct open_param       *op = &sr->arg.open;
 234  238          smb_attr_t              *ap = &op->fqi.fq_fattr;
 235  239          smb_ofile_t             *of;
 236  240          int                     rc;
 237      -        unsigned char           DirFlag;
      241 +        uint8_t                 DirFlag;
 238  242          uint32_t                status;
 239  243  
      244 +        if (op->create_options & ~SMB_NTCREATE_VALID_OPTIONS) {
      245 +                smbsr_error(sr, NT_STATUS_INVALID_PARAMETER,
      246 +                    ERRDOS, ERROR_INVALID_PARAMETER);
      247 +                return (SDRC_ERROR);
      248 +        }
      249 +
      250 +        if (op->create_options & FILE_OPEN_BY_FILE_ID) {
      251 +                smbsr_error(sr, NT_STATUS_NOT_SUPPORTED,
      252 +                    ERRDOS, ERROR_NOT_SUPPORTED);
      253 +                return (SDRC_ERROR);
      254 +        }
      255 +
 240  256          if ((op->create_options & FILE_DELETE_ON_CLOSE) &&
 241  257              !(op->desired_access & DELETE)) {
 242  258                  smbsr_error(sr, NT_STATUS_INVALID_PARAMETER,
 243  259                      ERRDOS, ERRbadaccess);
 244  260                  return (SDRC_ERROR);
 245  261          }
 246  262  
 247  263          if (op->create_disposition > FILE_MAXIMUM_DISPOSITION) {
 248  264                  smbsr_error(sr, NT_STATUS_INVALID_PARAMETER,
 249  265                      ERRDOS, ERRbadaccess);
↓ open down ↓ 17 lines elided ↑ open up ↑
 267  283          } else {
 268  284                  op->dir = smb_ofile_lookup_by_fid(sr, (uint16_t)op->rootdirfid);
 269  285                  if (op->dir == NULL) {
 270  286                          smbsr_error(sr, NT_STATUS_INVALID_HANDLE,
 271  287                              ERRDOS, ERRbadfid);
 272  288                          return (SDRC_ERROR);
 273  289                  }
 274  290                  op->fqi.fq_dnode = op->dir->f_node;
 275  291          }
 276  292  
 277      -        op->op_oplock_levelII = B_TRUE;
 278      -
 279  293          status = smb_common_open(sr);
 280  294          if (status != NT_STATUS_SUCCESS) {
 281  295                  smbsr_status(sr, status, 0, 0);
 282  296                  return (SDRC_ERROR);
 283  297          }
      298 +        if (op->op_oplock_level != SMB_OPLOCK_NONE) {
      299 +                /* Oplock req. in op->op_oplock_level etc. */
      300 +                smb1_oplock_acquire(sr, B_TRUE);
      301 +        }
 284  302  
 285  303          /*
 286  304           * NB: after the above smb_common_open() success,
 287  305           * we have a handle allocated (sr->fid_ofile).
 288  306           * If we don't return success, we must close it.
 289  307           */
 290  308          of = sr->fid_ofile;
 291  309  
 292  310          switch (sr->tid_tree->t_res_type & STYPE_MASK) {
 293  311          case STYPE_DISKTREE:
 294  312          case STYPE_PRINTQ:
 295  313                  if (op->create_options & FILE_DELETE_ON_CLOSE)
 296      -                        smb_ofile_set_delete_on_close(of);
 297      -
      314 +                        smb_ofile_set_delete_on_close(sr, of);
 298  315                  DirFlag = smb_node_is_dir(of->f_node) ? 1 : 0;
 299      -                rc = smbsr_encode_result(sr, 34, 0, "bb.wbwlTTTTlqqwwbw",
 300      -                    34,
 301      -                    sr->andx_com,
 302      -                    0x67,
 303      -                    op->op_oplock_level,
 304      -                    sr->smb_fid,
 305      -                    op->action_taken,
 306      -                    &ap->sa_crtime,
 307      -                    &ap->sa_vattr.va_atime,
 308      -                    &ap->sa_vattr.va_mtime,
 309      -                    &ap->sa_vattr.va_ctime,
 310      -                    op->dattr & FILE_ATTRIBUTE_MASK,
 311      -                    ap->sa_allocsz,
 312      -                    ap->sa_vattr.va_size,
 313      -                    op->ftype,
 314      -                    op->devstate,
 315      -                    DirFlag,
 316      -                    0);
 317  316                  break;
 318  317  
 319  318          case STYPE_IPC:
 320      -                rc = smbsr_encode_result(sr, 34, 0, "bb.wbwlqqqqlqqwwbw",
 321      -                    34,
 322      -                    sr->andx_com,
 323      -                    0x67,
 324      -                    0,
 325      -                    sr->smb_fid,
 326      -                    op->action_taken,
 327      -                    0LL,
 328      -                    0LL,
 329      -                    0LL,
 330      -                    0LL,
 331      -                    FILE_ATTRIBUTE_NORMAL,
 332      -                    0x1000LL,
 333      -                    0LL,
 334      -                    op->ftype,
 335      -                    op->devstate,
 336      -                    0,
 337      -                    0);
      319 +                DirFlag = 0;
 338  320                  break;
 339  321  
 340  322          default:
 341  323                  smbsr_error(sr, NT_STATUS_INVALID_DEVICE_REQUEST,
 342  324                      ERRDOS, ERROR_INVALID_FUNCTION);
 343  325                  goto errout;
 344  326          }
      327 +
      328 +        if ((op->nt_flags & NT_CREATE_FLAG_EXTENDED_RESPONSE) != 0 &&
      329 +            smb_nt_create_enable_extended_response != 0) {
      330 +                uint32_t MaxAccess = 0;
      331 +                if (of->f_node != NULL) {
      332 +                        smb_fsop_eaccess(sr, of->f_cr, of->f_node, &MaxAccess);
      333 +                }
      334 +                MaxAccess |= of->f_granted_access;
      335 +
      336 +                /*
      337 +                 * Here is a really ugly protocol wart in SMB1:
      338 +                 *
      339 +                 * [MS-SMB] Sec. 2.2.4.9.2: Windows-based SMB servers
      340 +                 * send 50 (0x32) words in the extended response although
      341 +                 * they set the WordCount field to 0x2A.
      342 +                 *
      343 +                 * In other words, THEY LIE!  We really do need to encode
      344 +                 * 50 words here, but lie and say we encoded 42 words.
      345 +                 * This means we can't use smbsr_encode_result() to
      346 +                 * build this response, because the rules it breaks
      347 +                 * would cause errors in smbsr_check_result().
      348 +                 *
      349 +                 * And that's not all (it gets worse...)
      350 +                 * Because of the bogus word count, some clients will
      351 +                 * read the byte count from within what should be the
      352 +                 * fileid field below.  Leave that zero, like Win7.
      353 +                 *
      354 +                 * Apparently the only really useful thing in this
      355 +                 * extended response is MaxAccess.
      356 +                 */
      357 +                sr->smb_wct = 50; /* real word count */
      358 +                sr->smb_bcc = 0;
      359 +                rc = smb_mbc_encodef(&sr->reply,
      360 +                    "bb.wbwlTTTTlqqwwb16.qllw",
      361 +                    42,         /* fake word count (b) */
      362 +                    sr->andx_com,               /* (b.) */
      363 +                    0x87,       /* andx offset     (w) */
      364 +                    op->op_oplock_level,        /* (b) */
      365 +                    sr->smb_fid,                /* (w) */
      366 +                    op->action_taken,           /* (l) */
      367 +                    &ap->sa_crtime,             /* (T) */
      368 +                    &ap->sa_vattr.va_atime,     /* (T) */
      369 +                    &ap->sa_vattr.va_mtime,     /* (T) */
      370 +                    &ap->sa_vattr.va_ctime,     /* (T) */
      371 +                    op->dattr & FILE_ATTRIBUTE_MASK, /* (l) */
      372 +                    ap->sa_allocsz,             /* (q) */
      373 +                    ap->sa_vattr.va_size,       /* (q) */
      374 +                    op->ftype,                  /* (w) */
      375 +                    op->devstate,               /* (w) */
      376 +                    DirFlag,                    /* (b) */
      377 +                    /* volume guid                (16.) */
      378 +                    0,  /* file ID (see above)     (q) */
      379 +                    MaxAccess,                  /* (l) */
      380 +                    0,          /* guest access    (l) */
      381 +                    0);         /* byte count      (w) */
      382 +        } else {
      383 +                rc = smbsr_encode_result(
      384 +                    sr, 34, 0, "bb.wbwlTTTTlqqwwbw",
      385 +                    34,         /* word count      (b) */
      386 +                    sr->andx_com,               /* (b.) */
      387 +                    0x67,       /* andx offset     (w) */
      388 +                    op->op_oplock_level,        /* (b) */
      389 +                    sr->smb_fid,                /* (w) */
      390 +                    op->action_taken,           /* (l) */
      391 +                    &ap->sa_crtime,             /* (T) */
      392 +                    &ap->sa_vattr.va_atime,     /* (T) */
      393 +                    &ap->sa_vattr.va_mtime,     /* (T) */
      394 +                    &ap->sa_vattr.va_ctime,     /* (T) */
      395 +                    op->dattr & FILE_ATTRIBUTE_MASK, /* (l) */
      396 +                    ap->sa_allocsz,             /* (q) */
      397 +                    ap->sa_vattr.va_size,       /* (q) */
      398 +                    op->ftype,                  /* (w) */
      399 +                    op->devstate,               /* (w) */
      400 +                    DirFlag,                    /* (b) */
      401 +                    0);         /* byte count      (w) */
      402 +        }
      403 +
 345  404          if (rc == 0)
 346  405                  return (SDRC_SUCCESS);
 347  406  
 348  407  errout:
 349  408          smb_ofile_close(of, 0);
 350  409          return (SDRC_ERROR);
 351  410  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX