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>
NEX-4239 smbtorture create failures re. allocation size
Reviewed by: Matt Barden <Matt.Barden@nexenta.com>
Reviewed by: Kevin Crowe <kevin.crowe@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)
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_open_andx.c
          +++ new/usr/src/uts/common/fs/smbsrv/smb_open_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 2015 Nexenta Systems, Inc.  All rights reserved.
       23 + * Copyright 2017 Nexenta Systems, Inc.  All rights reserved.
  24   24   */
  25   25  
  26   26  #include <smbsrv/smb_kproto.h>
       27 +#include <smbsrv/smb_fsops.h>
  27   28  #include <smbsrv/smb_vops.h>
  28   29  
  29   30  int smb_open_dsize_check = 0;
  30   31  
  31   32  /*
  32   33   *  Client Request                     Description
  33   34   *  ================================== =================================
  34   35   *
  35   36   *  UCHAR WordCount;                   Count of parameter words = 15
  36   37   *  UCHAR AndXCommand;                 Secondary (X) command;  0xFF =
↓ open down ↓ 182 lines elided ↑ open up ↑
 219  220  {
 220  221          struct open_param *op = &sr->arg.open;
 221  222          int rc;
 222  223  
 223  224          bzero(op, sizeof (sr->arg.open));
 224  225  
 225  226          rc = smbsr_decode_vwv(sr, "ww", &op->omode, &op->fqi.fq_sattr);
 226  227          if (rc == 0)
 227  228                  rc = smbsr_decode_data(sr, "%S", sr, &op->fqi.fq_path.pn_path);
 228  229  
 229      -        DTRACE_SMB_2(op__Open__start, smb_request_t *, sr,
 230      -            struct open_param *, op);
      230 +        DTRACE_SMB_START(op__Open, smb_request_t *, sr); /* arg.open */
 231  231  
 232  232          return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
 233  233  }
 234  234  
 235  235  void
 236  236  smb_post_open(smb_request_t *sr)
 237  237  {
 238      -        DTRACE_SMB_1(op__Open__done, smb_request_t *, sr);
      238 +        DTRACE_SMB_DONE(op__Open, smb_request_t *, sr);
 239  239  }
 240  240  
 241  241  smb_sdrc_t
 242  242  smb_com_open(smb_request_t *sr)
 243  243  {
 244  244          struct open_param *op = &sr->arg.open;
 245  245          smb_ofile_t *of;
 246      -        smb_attr_t attr;
      246 +        uint32_t mtime_sec;
 247  247          uint32_t status;
 248  248          uint16_t file_attr;
 249  249          int rc;
 250  250  
 251  251          op->desired_access = smb_omode_to_amask(op->omode);
 252  252          op->share_access = smb_denymode_to_sharemode(op->omode,
 253  253              op->fqi.fq_path.pn_path);
 254  254          op->crtime.tv_sec = op->crtime.tv_nsec = 0;
 255  255          op->create_disposition = FILE_OPEN;
 256  256          op->create_options = FILE_NON_DIRECTORY_FILE;
↓ open down ↓ 1 lines elided ↑ open up ↑
 258  258                  op->create_options |= FILE_WRITE_THROUGH;
 259  259  
 260  260          if (sr->smb_flg & SMB_FLAGS_OPLOCK) {
 261  261                  if (sr->smb_flg & SMB_FLAGS_OPLOCK_NOTIFY_ANY)
 262  262                          op->op_oplock_level = SMB_OPLOCK_BATCH;
 263  263                  else
 264  264                          op->op_oplock_level = SMB_OPLOCK_EXCLUSIVE;
 265  265          } else {
 266  266                  op->op_oplock_level = SMB_OPLOCK_NONE;
 267  267          }
 268      -        op->op_oplock_levelII = B_FALSE;
 269  268  
 270  269          if (smb_open_dsize_check && op->dsize > UINT_MAX) {
 271  270                  smbsr_error(sr, 0, ERRDOS, ERRbadaccess);
 272  271                  return (SDRC_ERROR);
 273  272          }
 274  273  
      274 +        /*
      275 +         * The real open call.   Note: this gets attributes into
      276 +         * op->fqi.fq_fattr (SMB_AT_ALL).  We need those below.
      277 +         */
 275  278          status = smb_common_open(sr);
 276  279          if (status != NT_STATUS_SUCCESS) {
 277  280                  smbsr_status(sr, status, 0, 0);
 278  281                  return (SDRC_ERROR);
 279  282          }
      283 +        if (op->op_oplock_level != SMB_OPLOCK_NONE) {
      284 +                /* Oplock req. in op->op_oplock_level etc. */
      285 +                smb1_oplock_acquire(sr, B_FALSE);
      286 +        }
 280  287  
 281  288          /*
 282  289           * NB: after the above smb_common_open() success,
 283  290           * we have a handle allocated (sr->fid_ofile).
 284  291           * If we don't return success, we must close it.
 285  292           */
 286  293          of = sr->fid_ofile;
 287  294  
 288  295          if (op->op_oplock_level == SMB_OPLOCK_NONE) {
 289  296                  sr->smb_flg &=
 290  297                      ~(SMB_FLAGS_OPLOCK | SMB_FLAGS_OPLOCK_NOTIFY_ANY);
 291  298          }
 292  299  
 293  300          file_attr = op->dattr & FILE_ATTRIBUTE_MASK;
 294      -        bzero(&attr, sizeof (attr));
 295      -        attr.sa_mask = SMB_AT_MTIME;
 296      -        rc = smb_node_getattr(sr, of->f_node, of->f_cr, of, &attr);
 297      -        if (rc != 0) {
 298      -                smbsr_errno(sr, rc);
 299      -                goto errout;
 300      -        }
      301 +        mtime_sec = smb_time_gmt_to_local(sr,
      302 +            op->fqi.fq_fattr.sa_vattr.va_mtime.tv_sec);
 301  303  
 302  304          rc = smbsr_encode_result(sr, 7, 0, "bwwllww",
 303  305              7,
 304  306              sr->smb_fid,
 305  307              file_attr,
 306      -            smb_time_gmt_to_local(sr, attr.sa_vattr.va_mtime.tv_sec),
      308 +            mtime_sec,
 307  309              (uint32_t)op->dsize,
 308  310              op->omode,
 309  311              (uint16_t)0);       /* bcc */
 310  312  
 311  313          if (rc == 0)
 312  314                  return (SDRC_SUCCESS);
 313  315  
 314      -errout:
 315  316          smb_ofile_close(of, 0);
 316  317          return (SDRC_ERROR);
 317  318  }
 318  319  
      320 +int smb_openx_enable_extended_response = 1;
      321 +
 319  322  /*
 320  323   * smb_pre_open_andx
 321  324   * For compatibility with windows servers, the search attributes
 322  325   * specified in the request are ignored.
 323  326   */
 324  327  smb_sdrc_t
 325  328  smb_pre_open_andx(smb_request_t *sr)
 326  329  {
 327  330          struct open_param *op = &sr->arg.open;
 328      -        uint16_t flags;
      331 +        uint16_t openx_flags;
 329  332          uint32_t alloc_size;
 330  333          uint32_t creation_time;
 331  334          uint16_t file_attr, sattr;
 332  335          int rc;
 333  336  
 334  337          bzero(op, sizeof (sr->arg.open));
 335  338  
 336  339          rc = smbsr_decode_vwv(sr, "b.wwwwwlwll4.", &sr->andx_com,
 337      -            &sr->andx_off, &flags, &op->omode, &sattr,
      340 +            &sr->andx_off, &openx_flags, &op->omode, &sattr,
 338  341              &file_attr, &creation_time, &op->ofun, &alloc_size, &op->timeo);
 339  342  
 340  343          if (rc == 0) {
 341  344                  rc = smbsr_decode_data(sr, "%u", sr, &op->fqi.fq_path.pn_path);
 342  345  
 343  346                  op->dattr = file_attr;
 344  347                  op->dsize = alloc_size;
 345  348  
 346      -                if (flags & 2)
 347      -                        op->op_oplock_level = SMB_OPLOCK_EXCLUSIVE;
 348      -                else if (flags & 4)
      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_OPBATCH)
 349  354                          op->op_oplock_level = SMB_OPLOCK_BATCH;
      355 +                else if (openx_flags & NT_CREATE_FLAG_REQUEST_OPLOCK)
      356 +                        op->op_oplock_level = SMB_OPLOCK_EXCLUSIVE;
 350  357                  else
 351  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;
 352  361  
 353  362                  if ((creation_time != 0) && (creation_time != UINT_MAX))
 354  363                          op->crtime.tv_sec =
 355  364                              smb_time_local_to_gmt(sr, creation_time);
 356  365                  op->crtime.tv_nsec = 0;
 357  366  
 358  367                  op->create_disposition = smb_ofun_to_crdisposition(op->ofun);
 359  368          }
 360  369  
 361      -        DTRACE_SMB_2(op__OpenX__start, smb_request_t *, sr,
 362      -            struct open_param *, op);
      370 +        DTRACE_SMB_START(op__OpenX, smb_request_t *, sr); /* arg.open */
 363  371  
 364  372          return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
 365  373  }
 366  374  
 367  375  void
 368  376  smb_post_open_andx(smb_request_t *sr)
 369  377  {
 370      -        DTRACE_SMB_1(op__OpenX__done, smb_request_t *, sr);
      378 +        DTRACE_SMB_DONE(op__OpenX, smb_request_t *, sr);
 371  379  }
 372  380  
 373  381  smb_sdrc_t
 374  382  smb_com_open_andx(smb_request_t *sr)
 375  383  {
 376  384          struct open_param       *op = &sr->arg.open;
      385 +        smb_attr_t              *ap = &op->fqi.fq_fattr;
 377  386          smb_ofile_t             *of;
 378  387          uint32_t                status;
      388 +        uint32_t                mtime_sec;
 379  389          uint16_t                file_attr;
 380      -        smb_attr_t              attr;
 381  390          int rc;
 382  391  
 383  392          op->desired_access = smb_omode_to_amask(op->omode);
 384  393          op->share_access = smb_denymode_to_sharemode(op->omode,
 385  394              op->fqi.fq_path.pn_path);
 386  395  
 387  396          if (op->create_disposition > FILE_MAXIMUM_DISPOSITION) {
 388  397                  smbsr_error(sr, 0, ERRDOS, ERRbadaccess);
 389  398                  return (SDRC_ERROR);
 390  399          }
 391  400  
 392  401          op->create_options = FILE_NON_DIRECTORY_FILE;
 393  402          if (op->omode & SMB_DA_WRITE_THROUGH)
 394  403                  op->create_options |= FILE_WRITE_THROUGH;
 395  404  
 396      -        op->op_oplock_levelII = B_FALSE;
 397      -
 398  405          if (smb_open_dsize_check && op->dsize > UINT_MAX) {
 399  406                  smbsr_error(sr, 0, ERRDOS, ERRbadaccess);
 400  407                  return (SDRC_ERROR);
 401  408          }
 402  409  
 403  410          status = smb_common_open(sr);
 404  411          if (status != NT_STATUS_SUCCESS) {
 405  412                  smbsr_status(sr, status, 0, 0);
 406  413                  return (SDRC_ERROR);
 407  414          }
      415 +        if (op->op_oplock_level != SMB_OPLOCK_NONE) {
      416 +                /* Oplock req. in op->op_oplock_level etc. */
      417 +                smb1_oplock_acquire(sr, B_FALSE);
      418 +        }
 408  419  
 409  420          /*
 410  421           * NB: after the above smb_common_open() success,
 411  422           * we have a handle allocated (sr->fid_ofile).
 412  423           * If we don't return success, we must close it.
 413  424           */
 414  425          of = sr->fid_ofile;
 415  426  
 416  427          if (op->op_oplock_level != SMB_OPLOCK_NONE)
 417      -                op->action_taken |= SMB_OACT_LOCK;
      428 +                op->action_taken |= SMB_OACT_OPLOCK;
 418  429          else
 419      -                op->action_taken &= ~SMB_OACT_LOCK;
      430 +                op->action_taken &= ~SMB_OACT_OPLOCK;
 420  431  
 421  432          file_attr = op->dattr & FILE_ATTRIBUTE_MASK;
 422      -        bzero(&attr, sizeof (attr));
      433 +        mtime_sec = smb_time_gmt_to_local(sr, ap->sa_vattr.va_mtime.tv_sec);
 423  434  
 424  435          switch (sr->tid_tree->t_res_type & STYPE_MASK) {
 425  436          case STYPE_DISKTREE:
 426  437          case STYPE_PRINTQ:
 427      -                attr.sa_mask = SMB_AT_MTIME;
 428      -                rc = smb_node_getattr(sr, of->f_node, of->f_cr, of, &attr);
 429      -                if (rc != 0) {
 430      -                        smbsr_errno(sr, rc);
 431      -                        goto errout;
 432      -                }
 433      -
 434      -                rc = smbsr_encode_result(sr, 15, 0,
 435      -                    "bb.wwwllwwwwl2.w",
 436      -                    15,
 437      -                    sr->andx_com, VAR_BCC,
 438      -                    sr->smb_fid,
 439      -                    file_attr,
 440      -                    smb_time_gmt_to_local(sr, attr.sa_vattr.va_mtime.tv_sec),
 441      -                    (uint32_t)op->dsize,
 442      -                    op->omode, op->ftype,
 443      -                    op->devstate,
 444      -                    op->action_taken, op->fileid,
 445      -                    0);
 446  438                  break;
 447  439  
 448  440          case STYPE_IPC:
 449      -                rc = smbsr_encode_result(sr, 15, 0,
 450      -                    "bb.wwwllwwwwl2.w",
 451      -                    15,
 452      -                    sr->andx_com, VAR_BCC,
 453      -                    sr->smb_fid,
 454      -                    file_attr,
 455      -                    0L,
 456      -                    0L,
 457      -                    op->omode, op->ftype,
 458      -                    op->devstate,
 459      -                    op->action_taken, op->fileid,
 460      -                    0);
      441 +                mtime_sec = 0;
 461  442                  break;
 462  443  
 463  444          default:
 464  445                  smbsr_error(sr, NT_STATUS_INVALID_DEVICE_REQUEST,
 465  446                      ERRDOS, ERROR_INVALID_FUNCTION);
 466  447                  goto errout;
 467  448          }
 468  449  
      450 +        if ((op->nt_flags & NT_CREATE_FLAG_EXTENDED_RESPONSE) != 0 &&
      451 +            smb_openx_enable_extended_response != 0) {
      452 +                uint32_t MaxAccess = 0;
      453 +                if (of->f_node != NULL) {
      454 +                        smb_fsop_eaccess(sr, of->f_cr, of->f_node, &MaxAccess);
      455 +                }
      456 +                MaxAccess |= of->f_granted_access;
      457 +
      458 +                rc = smbsr_encode_result(
      459 +                    sr, 19, 0, "bb.wwwllwwwwl2.llw",
      460 +                    19,         /* word count      (b) */
      461 +                    sr->andx_com,               /* (b.) */
      462 +                    VAR_BCC,    /* andx offset     (w) */
      463 +                    sr->smb_fid,                /* (w) */
      464 +                    file_attr,                  /* (w) */
      465 +                    mtime_sec,                  /* (l) */
      466 +                    (uint32_t)op->dsize,        /* (l) */
      467 +                    op->omode,                  /* (w) */
      468 +                    op->ftype,                  /* (w) */
      469 +                    op->devstate,               /* (w) */
      470 +                    op->action_taken,           /* (w) */
      471 +                    0,          /* legacy fileid   (l) */
      472 +                    /* reserved                   (2.) */
      473 +                    MaxAccess,                  /* (l) */
      474 +                    0,          /* guest access    (l) */
      475 +                    0);         /* byte count      (w) */
      476 +
      477 +        } else {
      478 +                rc = smbsr_encode_result(
      479 +                    sr, 15, 0, "bb.wwwllwwwwl2.w",
      480 +                    15,         /* word count      (b) */
      481 +                    sr->andx_com,               /* (b.) */
      482 +                    VAR_BCC,    /* andx offset     (w) */
      483 +                    sr->smb_fid,                /* (w) */
      484 +                    file_attr,                  /* (w) */
      485 +                    mtime_sec,                  /* (l) */
      486 +                    (uint32_t)op->dsize,        /* (l) */
      487 +                    op->omode,                  /* (w) */
      488 +                    op->ftype,                  /* (w) */
      489 +                    op->devstate,               /* (w) */
      490 +                    op->action_taken,           /* (w) */
      491 +                    0,          /* legacy fileid   (l) */
      492 +                    /* reserved                   (2.) */
      493 +                    0);         /* byte count      (w) */
      494 +        }
      495 +
 469  496          if (rc == 0)
 470  497                  return (SDRC_SUCCESS);
 471  498  
 472  499  errout:
 473  500          smb_ofile_close(of, 0);
 474  501          return (SDRC_ERROR);
 475  502  }
 476  503  
 477  504  smb_sdrc_t
 478  505  smb_com_trans2_open2(smb_request_t *sr, smb_xa_t *xa)
 479  506  {
 480  507          struct open_param *op = &sr->arg.open;
 481  508          uint32_t        creation_time;
 482  509          uint32_t        alloc_size;
      510 +        uint32_t        ea_list_size;
 483  511          uint16_t        flags;
 484  512          uint16_t        file_attr;
 485  513          uint32_t        status;
 486  514          int             rc;
 487  515  
 488  516          bzero(op, sizeof (sr->arg.open));
 489  517  
 490  518          rc = smb_mbc_decodef(&xa->req_param_mb, "%wwwwlwl10.u",
 491  519              sr, &flags, &op->omode, &op->fqi.fq_sattr, &file_attr,
 492  520              &creation_time, &op->ofun, &alloc_size, &op->fqi.fq_path.pn_path);
 493  521          if (rc != 0)
 494  522                  return (SDRC_ERROR);
 495  523  
      524 +        /*
      525 +         * The data part of this transaction may contain an EA list.
      526 +         * See: SMB_FEA_LIST ExtendedAttributeList
      527 +         *
      528 +         * If we find a non-empty EA list payload, return the special
      529 +         * error that tells the caller this FS does not suport EAs.
      530 +         *
      531 +         * Note: the first word is the size of the whole data segment,
      532 +         * INCLUDING the size of that length word.  That means if
      533 +         * the length word specifies a size less than four, it's
      534 +         * invalid (and probably a client trying something fishy).
      535 +         */
      536 +        rc = smb_mbc_decodef(&xa->req_data_mb, "l", &ea_list_size);
      537 +        if (rc == 0 && ea_list_size > 4) {
      538 +                smbsr_status(sr, NT_STATUS_EAS_NOT_SUPPORTED, 0, 0);
      539 +                return (SDRC_ERROR);
      540 +        }
      541 +
 496  542          if ((creation_time != 0) && (creation_time != UINT_MAX))
 497  543                  op->crtime.tv_sec = smb_time_local_to_gmt(sr, creation_time);
 498  544          op->crtime.tv_nsec = 0;
 499  545  
 500  546          op->dattr = file_attr;
 501  547          op->dsize = alloc_size;
 502  548          op->create_options = FILE_NON_DIRECTORY_FILE;
 503  549  
 504  550          op->desired_access = smb_omode_to_amask(op->omode);
 505  551          op->share_access = smb_denymode_to_sharemode(op->omode,
↓ open down ↓ 7 lines elided ↑ open up ↑
 513  559                  op->create_options |= FILE_WRITE_THROUGH;
 514  560  
 515  561          if (sr->smb_flg & SMB_FLAGS_OPLOCK) {
 516  562                  if (sr->smb_flg & SMB_FLAGS_OPLOCK_NOTIFY_ANY)
 517  563                          op->op_oplock_level = SMB_OPLOCK_BATCH;
 518  564                  else
 519  565                          op->op_oplock_level = SMB_OPLOCK_EXCLUSIVE;
 520  566          } else {
 521  567                  op->op_oplock_level = SMB_OPLOCK_NONE;
 522  568          }
 523      -        op->op_oplock_levelII = B_FALSE;
 524  569  
 525  570          status = smb_common_open(sr);
 526  571          if (status != NT_STATUS_SUCCESS) {
 527  572                  smbsr_status(sr, status, 0, 0);
 528  573                  return (SDRC_ERROR);
 529  574          }
      575 +        if (op->op_oplock_level != SMB_OPLOCK_NONE) {
      576 +                /* Oplock req. in op->op_oplock_level etc. */
      577 +                smb1_oplock_acquire(sr, B_FALSE);
      578 +        }
 530  579  
 531  580          if (op->op_oplock_level != SMB_OPLOCK_NONE)
 532      -                op->action_taken |= SMB_OACT_LOCK;
      581 +                op->action_taken |= SMB_OACT_OPLOCK;
 533  582          else
 534      -                op->action_taken &= ~SMB_OACT_LOCK;
      583 +                op->action_taken &= ~SMB_OACT_OPLOCK;
 535  584  
 536  585          file_attr = op->dattr & FILE_ATTRIBUTE_MASK;
 537  586  
 538  587          if (STYPE_ISIPC(sr->tid_tree->t_res_type))
 539  588                  op->dsize = 0;
 540  589  
 541  590          (void) smb_mbc_encodef(&xa->rep_param_mb, "wwllwwwwlwl",
 542  591              sr->smb_fid,
 543  592              file_attr,
 544  593              (uint32_t)0,        /* creation time */
↓ open down ↓ 11 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX