1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  23  * Copyright 2016 Nexenta Systems, Inc.  All rights reserved.
  24  */
  25 
  26 #include <smbsrv/smb_kproto.h>
  27 #include <smbsrv/smb_fsops.h>
  28 #include <smbsrv/smb_vops.h>
  29 
  30 int smb_open_dsize_check = 0;
  31 
  32 /*
  33  *  Client Request                     Description
  34  *  ================================== =================================
  35  *
  36  *  UCHAR WordCount;                   Count of parameter words = 15
  37  *  UCHAR AndXCommand;                 Secondary (X) command;  0xFF =
  38  *                                      none
  39  *  UCHAR AndXReserved;                Reserved (must be 0)
  40  *  USHORT AndXOffset;                 Offset to next command WordCount
  41  *  USHORT Flags;                      Additional information: bit set-
  42  *                                      0 - return additional info
  43  *                                      1 - exclusive oplock requested
  44  *                                      2 - batch oplock requested
  45  *  USHORT DesiredAccess;              File open mode
  46  *  USHORT SearchAttributes;
  47  *  USHORT FileAttributes;
  48  *  UTIME CreationTime;                Creation timestamp for file if it
  49  *                                      gets created
  50  *  USHORT OpenFunction;               Action to take if file exists
  51  *  ULONG AllocationSize;              Bytes to reserve on create or
  52  *                                      truncate
  53  *  ULONG Reserved[2];                 Must be 0
  54  *  USHORT ByteCount;                  Count of data bytes;    min = 1
  55  *  UCHAR BufferFormat                 0x04
  56  *  STRING FileName;
  57  *
  58  *  Server Response                    Description
  59  *  ================================== =================================
  60  *
  61  *  UCHAR WordCount;                   Count of parameter words = 15
  62  *  UCHAR AndXCommand;                 Secondary (X) command;  0xFF =
  63  *                                      none
  64  *  UCHAR AndXReserved;                Reserved (must be 0)
  65  *  USHORT AndXOffset;                 Offset to next command WordCount
  66  *  USHORT Fid;                        File handle
  67  *  USHORT FileAttributes;
  68  *  UTIME LastWriteTime;
  69  *  ULONG DataSize;                    Current file size
  70  *  USHORT GrantedAccess;              Access permissions actually
  71  *                                      allowed
  72  *  USHORT FileType;                   Type of file opened
  73  *  USHORT DeviceState;                State of the named pipe
  74  *  USHORT Action;                     Action taken
  75  *  ULONG ServerFid;                   Server unique file id
  76  *  USHORT Reserved;                   Reserved (must be 0)
  77  *  USHORT ByteCount;                  Count of data bytes = 0
  78  *
  79  * DesiredAccess describes the access the client desires for the file (see
  80  * section 3.6 -  Access Mode Encoding).
  81  *
  82  * OpenFunction specifies the action to be taken depending on whether or
  83  * not the file exists (see section 3.8 -  Open Function Encoding).  Action
  84  *
  85  * in the response specifies the action as a result of the Open request
  86  * (see section 3.9 -  Open Action Encoding).
  87  *
  88  * SearchAttributes indicates the attributes that the file must have to be
  89  * found while searching to see if it exists.  The encoding of this field
  90  * is described in the "File Attribute Encoding" section elsewhere in this
  91  * document.  If SearchAttributes is zero then only normal files are
  92  * returned.  If the system file, hidden or directory attributes are
  93  * specified then the search is inclusive -- both the specified type(s) of
  94  * files and normal files are returned.
  95  *
  96  * FileType returns the kind of resource actually opened:
  97  *
  98  *  Name                       Value  Description
  99  *  ========================== ====== ==================================
 100  *
 101  *  FileTypeDisk               0      Disk file or directory as defined
 102  *                                     in the attribute field
 103  *  FileTypeByteModePipe       1      Named pipe in byte mode
 104  *  FileTypeMessageModePipe    2      Named pipe in message mode
 105  *  FileTypePrinter            3      Spooled printer
 106  *  FileTypeUnknown            0xFFFF Unrecognized resource type
 107  *
 108  * If bit0 of Flags is clear, the FileAttributes, LastWriteTime, DataSize,
 109  * FileType, and DeviceState have indeterminate values in the response.
 110  *
 111  * This SMB can request an oplock on the opened file.  Oplocks are fully
 112  * described in the "Oplocks" section elsewhere in this document, and there
 113  * is also discussion of oplocks in the SMB_COM_LOCKING_ANDX SMB
 114  * description.  Bit1 and bit2 of the Flags field are used to request
 115  * oplocks during open.
 116  *
 117  * The following SMBs may follow SMB_COM_OPEN_ANDX:
 118  *
 119  *    SMB_COM_READ    SMB_COM_READ_ANDX
 120  *    SMB_COM_IOCTL
 121  */
 122 
 123 /*
 124  * This message is sent to obtain a file handle for a data file.  This
 125  * returned Fid is used in subsequent client requests such as read, write,
 126  * close, etc.
 127  *
 128  * Client Request                     Description
 129  * ================================== =================================
 130  *
 131  * UCHAR WordCount;                   Count of parameter words = 2
 132  * USHORT DesiredAccess;              Mode - read/write/share
 133  * USHORT SearchAttributes;
 134  * USHORT ByteCount;                  Count of data bytes;    min = 2
 135  * UCHAR BufferFormat;                0x04
 136  * STRING FileName[];                 File name
 137  *
 138  * FileName is the fully qualified file name, relative to the root of the
 139  * share specified in the Tid field of the SMB header.  If Tid in the SMB
 140  * header refers to a print share, this SMB creates a new file which will
 141  * be spooled to the printer when closed.  In this case, FileName is
 142  * ignored.
 143  *
 144  * SearchAttributes specifies the type of file desired.  The encoding is
 145  * described in the "File Attribute Encoding" section.
 146  *
 147  * DesiredAccess controls the mode under which the file is opened, and the
 148  * file will be opened only if the client has the appropriate permissions.
 149  * The encoding of DesiredAccess is discussed in the section entitled
 150  * "Access Mode Encoding".
 151  *
 152  * Server Response                    Description
 153  * ================================== =================================
 154  *
 155  * UCHAR WordCount;                   Count of parameter words = 7
 156  * USHORT Fid;                        File handle
 157  * USHORT FileAttributes;             Attributes of opened file
 158  * UTIME LastWriteTime;               Time file was last written
 159  * ULONG DataSize;                    File size
 160  * USHORT GrantedAccess;              Access allowed
 161  * USHORT ByteCount;                  Count of data bytes = 0
 162  *
 163  * Fid is the handle value which should be used for subsequent file
 164  * operations.
 165  *
 166  * FileAttributes specifies the type of file obtained.  The encoding is
 167  * described in the "File Attribute Encoding" section.
 168  *
 169  * GrantedAccess indicates the access permissions actually allowed, and may
 170  * have one of the following values:
 171  *
 172  *    0  read-only
 173  *    1  write-only
 174  *    2 read/write
 175  *
 176  * File Handles (Fids) are scoped per client.  A Pid may reference any Fid
 177  * established by itself or any other Pid on the client (so far as the
 178  * server is concerned).  The actual accesses allowed through the Fid
 179  * depends on the open and deny modes specified when the file was opened
 180  * (see below).
 181  *
 182  * The MS-DOS compatibility mode of file open provides exclusion at the
 183  * client level.  A file open in compatibility mode may be opened (also in
 184  * compatibility mode) any number of times for any combination of reading
 185  * and writing (subject to the user's permissions) by any Pid on the same
 186  * client.  If the first client has the file open for writing, then the
 187  * file may not be opened in any way by any other client.  If the first
 188  * client has the file open only for reading, then other clients may open
 189  * the file, in compatibility mode, for reading..  The above
 190  * notwithstanding, if the filename has an extension of .EXE, .DLL, .SYM,
 191  * or .COM other clients are permitted to open the file regardless of
 192  * read/write open modes of other compatibility mode opens.  However, once
 193  * multiple clients have the file open for reading, no client is permitted
 194  * to open the file for writing and no other client may open the file in
 195  * any mode other than compatibility mode.
 196  *
 197  * The other file exclusion modes (Deny read/write, Deny write, Deny read,
 198  * Deny none) provide exclusion at the file level.  A file opened in any
 199  * "Deny" mode may be opened again only for the accesses allowed by the
 200  * Deny mode (subject to the user's permissions).  This is true regardless
 201  * of the identity of the second opener -a different client, a Pid from the
 202  * same client, or the Pid that already has the file open.  For example, if
 203  * a file is open in "Deny write" mode a second open may only obtain read
 204  * permission to the file.
 205  *
 206  * Although Fids are available to all Pids on a client, Pids other than the
 207  * owner may not have the full access rights specified in the open mode by
 208  * the Fid's creator.  If the open creating the Fid specified a deny mode,
 209  * then any Pid using the Fid, other than the creating Pid, will have only
 210  * those access rights determined by "anding" the open mode rights and the
 211  * deny mode rights, i.e., the deny mode is checked on all file accesses.
 212  * For example, if a file is opened for Read/Write in Deny write mode, then
 213  * other clients may only read the file and cannot write; if a file is
 214  * opened for Read in Deny read mode, then the other clients can neither
 215  * read nor write the file.
 216  */
 217 
 218 smb_sdrc_t
 219 smb_pre_open(smb_request_t *sr)
 220 {
 221         struct open_param *op = &sr->arg.open;
 222         int rc;
 223 
 224         bzero(op, sizeof (sr->arg.open));
 225 
 226         rc = smbsr_decode_vwv(sr, "ww", &op->omode, &op->fqi.fq_sattr);
 227         if (rc == 0)
 228                 rc = smbsr_decode_data(sr, "%S", sr, &op->fqi.fq_path.pn_path);
 229 
 230         DTRACE_SMB_2(op__Open__start, smb_request_t *, sr,
 231             struct open_param *, op);
 232 
 233         return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
 234 }
 235 
 236 void
 237 smb_post_open(smb_request_t *sr)
 238 {
 239         DTRACE_SMB_1(op__Open__done, smb_request_t *, sr);
 240 }
 241 
 242 smb_sdrc_t
 243 smb_com_open(smb_request_t *sr)
 244 {
 245         struct open_param *op = &sr->arg.open;
 246         smb_ofile_t *of;
 247         smb_attr_t attr;
 248         uint32_t status;
 249         uint16_t file_attr;
 250         int rc;
 251 
 252         op->desired_access = smb_omode_to_amask(op->omode);
 253         op->share_access = smb_denymode_to_sharemode(op->omode,
 254             op->fqi.fq_path.pn_path);
 255         op->crtime.tv_sec = op->crtime.tv_nsec = 0;
 256         op->create_disposition = FILE_OPEN;
 257         op->create_options = FILE_NON_DIRECTORY_FILE;
 258         if (op->omode & SMB_DA_WRITE_THROUGH)
 259                 op->create_options |= FILE_WRITE_THROUGH;
 260 
 261         if (sr->smb_flg & SMB_FLAGS_OPLOCK) {
 262                 if (sr->smb_flg & SMB_FLAGS_OPLOCK_NOTIFY_ANY)
 263                         op->op_oplock_level = SMB_OPLOCK_BATCH;
 264                 else
 265                         op->op_oplock_level = SMB_OPLOCK_EXCLUSIVE;
 266         } else {
 267                 op->op_oplock_level = SMB_OPLOCK_NONE;
 268         }
 269         op->op_oplock_levelII = B_FALSE;
 270 
 271         if (smb_open_dsize_check && op->dsize > UINT_MAX) {
 272                 smbsr_error(sr, 0, ERRDOS, ERRbadaccess);
 273                 return (SDRC_ERROR);
 274         }
 275 
 276         status = smb_common_open(sr);
 277         if (status != NT_STATUS_SUCCESS) {
 278                 smbsr_status(sr, status, 0, 0);
 279                 return (SDRC_ERROR);
 280         }
 281 
 282         /*
 283          * NB: after the above smb_common_open() success,
 284          * we have a handle allocated (sr->fid_ofile).
 285          * If we don't return success, we must close it.
 286          */
 287         of = sr->fid_ofile;
 288 
 289         if (op->op_oplock_level == SMB_OPLOCK_NONE) {
 290                 sr->smb_flg &=
 291                     ~(SMB_FLAGS_OPLOCK | SMB_FLAGS_OPLOCK_NOTIFY_ANY);
 292         }
 293 
 294         file_attr = op->dattr & FILE_ATTRIBUTE_MASK;
 295         bzero(&attr, sizeof (attr));
 296         attr.sa_mask = SMB_AT_MTIME;
 297         rc = smb_node_getattr(sr, of->f_node, of->f_cr, of, &attr);
 298         if (rc != 0) {
 299                 smbsr_errno(sr, rc);
 300                 goto errout;
 301         }
 302 
 303         rc = smbsr_encode_result(sr, 7, 0, "bwwllww",
 304             7,
 305             sr->smb_fid,
 306             file_attr,
 307             smb_time_gmt_to_local(sr, attr.sa_vattr.va_mtime.tv_sec),
 308             (uint32_t)op->dsize,
 309             op->omode,
 310             (uint16_t)0);       /* bcc */
 311 
 312         if (rc == 0)
 313                 return (SDRC_SUCCESS);
 314 
 315 errout:
 316         smb_ofile_close(of, 0);
 317         return (SDRC_ERROR);
 318 }
 319 
 320 int smb_openx_enable_extended_response = 1;
 321 
 322 /*
 323  * smb_pre_open_andx
 324  * For compatibility with windows servers, the search attributes
 325  * specified in the request are ignored.
 326  */
 327 smb_sdrc_t
 328 smb_pre_open_andx(smb_request_t *sr)
 329 {
 330         struct open_param *op = &sr->arg.open;
 331         uint16_t openx_flags;
 332         uint32_t alloc_size;
 333         uint32_t creation_time;
 334         uint16_t file_attr, sattr;
 335         int rc;
 336 
 337         bzero(op, sizeof (sr->arg.open));
 338 
 339         rc = smbsr_decode_vwv(sr, "b.wwwwwlwll4.", &sr->andx_com,
 340             &sr->andx_off, &openx_flags, &op->omode, &sattr,
 341             &file_attr, &creation_time, &op->ofun, &alloc_size, &op->timeo);
 342 
 343         if (rc == 0) {
 344                 rc = smbsr_decode_data(sr, "%u", sr, &op->fqi.fq_path.pn_path);
 345 
 346                 op->dattr = file_attr;
 347                 op->dsize = alloc_size;
 348 
 349                 /*
 350                  * The openx_flags use some "extended" flags that
 351                  * happen to match some of the NtCreateX flags.
 352                  */
 353                 if (openx_flags & NT_CREATE_FLAG_REQUEST_OPLOCK)
 354                         op->op_oplock_level = SMB_OPLOCK_EXCLUSIVE;
 355                 else if (openx_flags & NT_CREATE_FLAG_REQUEST_OPBATCH)
 356                         op->op_oplock_level = SMB_OPLOCK_BATCH;
 357                 else
 358                         op->op_oplock_level = SMB_OPLOCK_NONE;
 359                 if (openx_flags & NT_CREATE_FLAG_EXTENDED_RESPONSE)
 360                         op->nt_flags |= NT_CREATE_FLAG_EXTENDED_RESPONSE;
 361 
 362                 if ((creation_time != 0) && (creation_time != UINT_MAX))
 363                         op->crtime.tv_sec =
 364                             smb_time_local_to_gmt(sr, creation_time);
 365                 op->crtime.tv_nsec = 0;
 366 
 367                 op->create_disposition = smb_ofun_to_crdisposition(op->ofun);
 368         }
 369 
 370         DTRACE_SMB_2(op__OpenX__start, smb_request_t *, sr,
 371             struct open_param *, op);
 372 
 373         return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
 374 }
 375 
 376 void
 377 smb_post_open_andx(smb_request_t *sr)
 378 {
 379         DTRACE_SMB_1(op__OpenX__done, smb_request_t *, sr);
 380 }
 381 
 382 smb_sdrc_t
 383 smb_com_open_andx(smb_request_t *sr)
 384 {
 385         struct open_param       *op = &sr->arg.open;
 386         smb_attr_t              *ap = &op->fqi.fq_fattr;
 387         smb_ofile_t             *of;
 388         uint32_t                status;
 389         uint32_t                mtime_sec;
 390         uint16_t                file_attr;
 391         int rc;
 392 
 393         op->desired_access = smb_omode_to_amask(op->omode);
 394         op->share_access = smb_denymode_to_sharemode(op->omode,
 395             op->fqi.fq_path.pn_path);
 396 
 397         if (op->create_disposition > FILE_MAXIMUM_DISPOSITION) {
 398                 smbsr_error(sr, 0, ERRDOS, ERRbadaccess);
 399                 return (SDRC_ERROR);
 400         }
 401 
 402         op->create_options = FILE_NON_DIRECTORY_FILE;
 403         if (op->omode & SMB_DA_WRITE_THROUGH)
 404                 op->create_options |= FILE_WRITE_THROUGH;
 405 
 406         op->op_oplock_levelII = B_FALSE;
 407 
 408         if (smb_open_dsize_check && op->dsize > UINT_MAX) {
 409                 smbsr_error(sr, 0, ERRDOS, ERRbadaccess);
 410                 return (SDRC_ERROR);
 411         }
 412 
 413         status = smb_common_open(sr);
 414         if (status != NT_STATUS_SUCCESS) {
 415                 smbsr_status(sr, status, 0, 0);
 416                 return (SDRC_ERROR);
 417         }
 418 
 419         /*
 420          * NB: after the above smb_common_open() success,
 421          * we have a handle allocated (sr->fid_ofile).
 422          * If we don't return success, we must close it.
 423          */
 424         of = sr->fid_ofile;
 425 
 426         if (op->op_oplock_level != SMB_OPLOCK_NONE)
 427                 op->action_taken |= SMB_OACT_OPLOCK;
 428         else
 429                 op->action_taken &= ~SMB_OACT_OPLOCK;
 430 
 431         file_attr = op->dattr & FILE_ATTRIBUTE_MASK;
 432         mtime_sec = smb_time_gmt_to_local(sr, ap->sa_vattr.va_mtime.tv_sec);
 433 
 434         switch (sr->tid_tree->t_res_type & STYPE_MASK) {
 435         case STYPE_DISKTREE:
 436         case STYPE_PRINTQ:
 437                 break;
 438 
 439         case STYPE_IPC:
 440                 mtime_sec = 0;
 441                 break;
 442 
 443         default:
 444                 smbsr_error(sr, NT_STATUS_INVALID_DEVICE_REQUEST,
 445                     ERRDOS, ERROR_INVALID_FUNCTION);
 446                 goto errout;
 447         }
 448 
 449         if ((op->nt_flags & NT_CREATE_FLAG_EXTENDED_RESPONSE) != 0 &&
 450             smb_openx_enable_extended_response != 0) {
 451                 uint32_t MaxAccess = 0;
 452                 if (of->f_node != NULL) {
 453                         smb_fsop_eaccess(sr, of->f_cr, of->f_node, &MaxAccess);
 454                 }
 455                 MaxAccess |= of->f_granted_access;
 456 
 457                 rc = smbsr_encode_result(
 458                     sr, 19, 0, "bb.wwwllwwwwl2.llw",
 459                     19,         /* word count      (b) */
 460                     sr->andx_com,            /* (b.) */
 461                     VAR_BCC,    /* andx offset     (w) */
 462                     sr->smb_fid,             /* (w) */
 463                     file_attr,                  /* (w) */
 464                     mtime_sec,                  /* (l) */
 465                     (uint32_t)op->dsize,     /* (l) */
 466                     op->omode,                       /* (w) */
 467                     op->ftype,                       /* (w) */
 468                     op->devstate,            /* (w) */
 469                     op->action_taken,                /* (w) */
 470                     0,          /* legacy fileid   (l) */
 471                     /* reserved                   (2.) */
 472                     MaxAccess,                  /* (l) */
 473                     0,          /* guest access    (l) */
 474                     0);         /* byte count      (w) */
 475 
 476         } else {
 477                 rc = smbsr_encode_result(
 478                     sr, 15, 0, "bb.wwwllwwwwl2.w",
 479                     15,         /* word count      (b) */
 480                     sr->andx_com,            /* (b.) */
 481                     VAR_BCC,    /* andx offset     (w) */
 482                     sr->smb_fid,             /* (w) */
 483                     file_attr,                  /* (w) */
 484                     mtime_sec,                  /* (l) */
 485                     (uint32_t)op->dsize,     /* (l) */
 486                     op->omode,                       /* (w) */
 487                     op->ftype,                       /* (w) */
 488                     op->devstate,            /* (w) */
 489                     op->action_taken,                /* (w) */
 490                     0,          /* legacy fileid   (l) */
 491                     /* reserved                   (2.) */
 492                     0);         /* byte count      (w) */
 493         }
 494 
 495         if (rc == 0)
 496                 return (SDRC_SUCCESS);
 497 
 498 errout:
 499         smb_ofile_close(of, 0);
 500         return (SDRC_ERROR);
 501 }
 502 
 503 smb_sdrc_t
 504 smb_com_trans2_open2(smb_request_t *sr, smb_xa_t *xa)
 505 {
 506         struct open_param *op = &sr->arg.open;
 507         uint32_t        creation_time;
 508         uint32_t        alloc_size;
 509         uint32_t        ea_list_size;
 510         uint16_t        flags;
 511         uint16_t        file_attr;
 512         uint32_t        status;
 513         int             rc;
 514 
 515         bzero(op, sizeof (sr->arg.open));
 516 
 517         rc = smb_mbc_decodef(&xa->req_param_mb, "%wwwwlwl10.u",
 518             sr, &flags, &op->omode, &op->fqi.fq_sattr, &file_attr,
 519             &creation_time, &op->ofun, &alloc_size, &op->fqi.fq_path.pn_path);
 520         if (rc != 0)
 521                 return (SDRC_ERROR);
 522 
 523         /*
 524          * The data part of this transaction may contain an EA list.
 525          * See: SMB_FEA_LIST ExtendedAttributeList
 526          *
 527          * If we find a non-empty EA list payload, return the special
 528          * error that tells the caller this FS does not suport EAs.
 529          *
 530          * Note: the first word is the size of the whole data segment,
 531          * INCLUDING the size of that length word.  That means if
 532          * the length word specifies a size less than four, it's
 533          * invalid (and probably a client trying something fishy).
 534          */
 535         rc = smb_mbc_decodef(&xa->req_data_mb, "l", &ea_list_size);
 536         if (rc == 0 && ea_list_size > 4) {
 537                 smbsr_status(sr, NT_STATUS_EAS_NOT_SUPPORTED, 0, 0);
 538                 return (SDRC_ERROR);
 539         }
 540 
 541         if ((creation_time != 0) && (creation_time != UINT_MAX))
 542                 op->crtime.tv_sec = smb_time_local_to_gmt(sr, creation_time);
 543         op->crtime.tv_nsec = 0;
 544 
 545         op->dattr = file_attr;
 546         op->dsize = alloc_size;
 547         op->create_options = FILE_NON_DIRECTORY_FILE;
 548 
 549         op->desired_access = smb_omode_to_amask(op->omode);
 550         op->share_access = smb_denymode_to_sharemode(op->omode,
 551             op->fqi.fq_path.pn_path);
 552 
 553         op->create_disposition = smb_ofun_to_crdisposition(op->ofun);
 554         if (op->create_disposition > FILE_MAXIMUM_DISPOSITION)
 555                 op->create_disposition = FILE_CREATE;
 556 
 557         if (op->omode & SMB_DA_WRITE_THROUGH)
 558                 op->create_options |= FILE_WRITE_THROUGH;
 559 
 560         if (sr->smb_flg & SMB_FLAGS_OPLOCK) {
 561                 if (sr->smb_flg & SMB_FLAGS_OPLOCK_NOTIFY_ANY)
 562                         op->op_oplock_level = SMB_OPLOCK_BATCH;
 563                 else
 564                         op->op_oplock_level = SMB_OPLOCK_EXCLUSIVE;
 565         } else {
 566                 op->op_oplock_level = SMB_OPLOCK_NONE;
 567         }
 568         op->op_oplock_levelII = B_FALSE;
 569 
 570         status = smb_common_open(sr);
 571         if (status != NT_STATUS_SUCCESS) {
 572                 smbsr_status(sr, status, 0, 0);
 573                 return (SDRC_ERROR);
 574         }
 575 
 576         if (op->op_oplock_level != SMB_OPLOCK_NONE)
 577                 op->action_taken |= SMB_OACT_OPLOCK;
 578         else
 579                 op->action_taken &= ~SMB_OACT_OPLOCK;
 580 
 581         file_attr = op->dattr & FILE_ATTRIBUTE_MASK;
 582 
 583         if (STYPE_ISIPC(sr->tid_tree->t_res_type))
 584                 op->dsize = 0;
 585 
 586         (void) smb_mbc_encodef(&xa->rep_param_mb, "wwllwwwwlwl",
 587             sr->smb_fid,
 588             file_attr,
 589             (uint32_t)0,        /* creation time */
 590             (uint32_t)op->dsize,
 591             op->omode,
 592             op->ftype,
 593             op->devstate,
 594             op->action_taken,
 595             op->fileid,
 596             (uint16_t)0,        /* EA error offset */
 597             (uint32_t)0);       /* EA list length */
 598 
 599         return (SDRC_SUCCESS);
 600 }