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 2014 Nexenta Systems, Inc.  All rights reserved.
  14  */
  15 
  16 /*
  17  * Dispatch function for SMB2_SET_INFO
  18  */
  19 
  20 #include <smbsrv/smb2_kproto.h>
  21 #include <smbsrv/smb_fsops.h>
  22 #include <smbsrv/ntifs.h>
  23 
  24 smb_sdrc_t
  25 smb2_set_info(smb_request_t *sr)
  26 {
  27         smb_setinfo_t sinfo;
  28         uint16_t StructSize;
  29         uint16_t iBufOffset;
  30         uint32_t iBufLength;
  31         uint32_t AddlInfo;
  32         smb2fid_t smb2fid;
  33         uint32_t status;
  34         uint8_t InfoType, InfoClass;
  35         smb_sdrc_t sdrc = SDRC_SUCCESS;
  36         int rc = 0;
  37 
  38         bzero(&sinfo, sizeof (sinfo));
  39 
  40         /*
  41          * SMB2 Set Info request
  42          */
  43         rc = smb_mbc_decodef(
  44             &sr->smb_data, "wbblw..lqq",
  45             &StructSize,            /* w */
  46             &InfoType,                      /* b */
  47             &InfoClass,                     /* b */
  48             &iBufLength,            /* l */
  49             &iBufOffset,            /* w */
  50             /* reserved                   .. */
  51             &AddlInfo,                      /* l */
  52             &smb2fid.persistent,    /* q */
  53             &smb2fid.temporal);             /* q */
  54         if (rc || StructSize != 33) {
  55                 sdrc = SDRC_ERROR;
  56                 return (sdrc);
  57         }
  58 
  59         if (iBufLength > smb2_max_trans) {
  60                 status = NT_STATUS_INVALID_PARAMETER;
  61                 goto errout;
  62         }
  63 
  64         status = smb2sr_lookup_fid(sr, &smb2fid);
  65         if (status)
  66                 goto errout;
  67 
  68         sinfo.si_node = sr->fid_ofile->f_node;
  69         sr->user_cr = sr->fid_ofile->f_cr;
  70 
  71         /*
  72          * If there's an input buffer, setup a shadow.
  73          */
  74         if (iBufLength) {
  75                 rc = MBC_SHADOW_CHAIN(&sinfo.si_data, &sr->smb_data,
  76                     sr->smb2_cmd_hdr + iBufOffset, iBufLength);
  77                 if (rc) {
  78                         status = NT_STATUS_INVALID_PARAMETER;
  79                         goto errout;
  80                 }
  81         }
  82 
  83         /* No output data. */
  84         sr->raw_data.max_bytes = 0;
  85 
  86         switch (InfoType) {
  87         case SMB2_0_INFO_FILE:
  88                 status = smb2_setinfo_file(sr, &sinfo, InfoClass);
  89                 break;
  90         case SMB2_0_INFO_FILESYSTEM:
  91                 status = smb2_setinfo_fs(sr, &sinfo, InfoClass);
  92                 break;
  93         case SMB2_0_INFO_SECURITY:
  94                 status = smb2_setinfo_sec(sr, &sinfo, AddlInfo);
  95                 break;
  96         case SMB2_0_INFO_QUOTA:
  97                 status = smb2_setinfo_quota(sr, &sinfo);
  98                 break;
  99         default:
 100                 status = NT_STATUS_INVALID_PARAMETER;
 101                 break;
 102         }
 103 
 104         if (status) {
 105         errout:
 106                 smb2sr_put_error(sr, status);
 107                 return (sdrc);
 108         }
 109 
 110         /*
 111          * SMB2 Query Info reply
 112          */
 113         rc = smb_mbc_encodef(
 114             &sr->reply, "w..",
 115             2); /* StructSize */        /* w */
 116         if (rc)
 117                 sdrc = SDRC_ERROR;
 118 
 119         return (sdrc);
 120 }