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 /*
  27  * This command is used to create or open a file or directory.
  28  */
  29 
  30 
  31 #include <smbsrv/smb_kproto.h>
  32 #include <smbsrv/smb_fsops.h>
  33 #include <smbsrv/smb_vops.h>
  34 
  35 int smb_nt_create_enable_extended_response = 1;
  36 
  37 /*
  38  * smb_com_nt_create_andx
  39  *
  40  * This command is used to create or open a file or directory.
  41  *
  42  *  Client Request                     Description
  43  *  =================================  ==================================
  44  *
  45  *  UCHAR WordCount;                   Count of parameter words = 24
  46  *  UCHAR AndXCommand;                 Secondary command;  0xFF = None
  47  *  UCHAR AndXReserved;                Reserved (must be 0)
  48  *  USHORT AndXOffset;                 Offset to next command WordCount
  49  *  UCHAR Reserved;                    Reserved (must be 0)
  50  *  USHORT NameLength;                 Length of Name[] in bytes
  51  *  ULONG Flags;                       Create bit set:
  52  *                                     0x02 - Request an oplock
  53  *                                     0x04 - Request a batch oplock
  54  *                                     0x08 - Target of open must be
  55  *                                     directory
  56  *  ULONG RootDirectoryFid;            If non-zero, open is relative to
  57  *                                     this directory
  58  *  ACCESS_MASK DesiredAccess;         access desired
  59  *  LARGE_INTEGER AllocationSize;      Initial allocation size
  60  *  ULONG ExtFileAttributes;           File attributes
  61  *  ULONG ShareAccess;                 Type of share access
  62  *  ULONG CreateDisposition;           Action to take if file exists or
  63  *                                     not
  64  *  ULONG CreateOptions;               Options to use if creating a file
  65  *  ULONG ImpersonationLevel;          Security QOS information
  66  *  UCHAR SecurityFlags;               Security tracking mode flags:
  67  *                                     0x1 - SECURITY_CONTEXT_TRACKING
  68  *                                     0x2 - SECURITY_EFFECTIVE_ONLY
  69  *  USHORT ByteCount;                  Length of byte parameters
  70  *  STRING Name[];                     File to open or create
  71  *
  72  * The DesiredAccess parameter is specified in section 3.7 on  Access Mask
  73  * Encoding.
  74  *
  75  * If no value is specified, it still allows an application to query
  76  * attributes without actually accessing the file.
  77  *
  78  * The ExtFIleAttributes parameter specifies the file attributes and flags
  79  * for the file. The parameter's value is the sum of allowed attributes and
  80  * flags defined in section 3.11 on  Extended File Attribute Encoding
  81  *
  82  * The ShareAccess field Specifies how this file can be shared. This
  83  * parameter must be some combination of the following values:
  84  *
  85  * Name              Value      Meaning
  86  *                   0          Prevents the file from being shared.
  87  * FILE_SHARE_READ   0x00000001 Other open operations can be performed on
  88  *                               the file for read access.
  89  * FILE_SHARE_WRITE  0x00000002 Other open operations can be performed on
  90  *                               the file for write access.
  91  * FILE_SHARE_DELETE 0x00000004 Other open operations can be performed on
  92  *                               the file for delete access.
  93  *
  94  * The CreateDisposition parameter can contain one of the following values:
  95  *
  96  * CREATE_NEW        Creates a new file. The function fails if the
  97  *                   specified file already exists.
  98  * CREATE_ALWAYS     Creates a new file. The function overwrites the file
  99  *                   if it exists.
 100  * OPEN_EXISTING     Opens the file. The function fails if the file does
 101  *                   not exist.
 102  * OPEN_ALWAYS       Opens the file, if it exists. If the file does not
 103  *                   exist, act like CREATE_NEW.
 104  * TRUNCATE_EXISTING Opens the file. Once opened, the file is truncated so
 105  *                   that its size is zero bytes. The calling process must
 106  *                   open the file with at least GENERIC_WRITE access. The
 107  *                   function fails if the file does not exist.
 108  *
 109  * The ImpersonationLevel parameter can contain one or more of the
 110  * following values:
 111  *
 112  * SECURITY_ANONYMOUS        Specifies to impersonate the client at the
 113  *                           Anonymous impersonation level.
 114  * SECURITY_IDENTIFICATION   Specifies to impersonate the client at the
 115  *                           Identification impersonation level.
 116  * SECURITY_IMPERSONATION    Specifies to impersonate the client at the
 117  *                           Impersonation impersonation level.
 118  * SECURITY_DELEGATION       Specifies to impersonate the client at the
 119  *                           Delegation impersonation level.
 120  *
 121  * The SecurityFlags parameter can have either of the following two flags
 122  * set:
 123  *
 124  * SECURITY_CONTEXT_TRACKING  Specifies that the security tracking mode is
 125  *                            dynamic. If this flag is not specified,
 126  *                            Security Tracking Mode is static.
 127  * SECURITY_EFFECTIVE_ONLY    Specifies that only the enabled aspects of
 128  *                            the client's security context are available
 129  *                            to the server. If you do not specify this
 130  *                            flag, all aspects of the client's security
 131  *                            context are available. This flag allows the
 132  *                            client to limit the groups and privileges
 133  *                            that a server can use while impersonating the
 134  *                            client.
 135  *
 136  * The response is as follows:
 137  *
 138  *  Server Response                    Description
 139  *  =================================  ==================================
 140  *
 141  *  UCHAR WordCount;                   Count of parameter words = 26
 142  *  UCHAR AndXCommand;  Secondary      0xFF = None
 143  *  command;
 144  *  UCHAR AndXReserved;                MBZ
 145  *  USHORT AndXOffset;                 Offset to next command WordCount
 146  *  UCHAR OplockLevel;                 The oplock level granted
 147  *                                     0 - No oplock granted
 148  *                                     1 - Exclusive oplock granted
 149  *                                     2 - Batch oplock granted
 150  *                                     3 - Level II oplock granted
 151  *  USHORT Fid;                        The file ID
 152  *  ULONG CreateAction;                The action taken
 153  *  TIME CreationTime;                 The time the file was created
 154  *  TIME LastAccessTime;               The time the file was accessed
 155  *  TIME LastWriteTime;                The time the file was last written
 156  *  TIME ChangeTime;                   The time the file was last changed
 157  *  ULONG ExtFileAttributes;           The file attributes
 158  *  LARGE_INTEGER AllocationSize;      The number of bytes allocated
 159  *  LARGE_INTEGER EndOfFile;           The end of file offset
 160  *  USHORT FileType;
 161  *  USHORT DeviceState;                state of IPC device (e.g. pipe)
 162  *  BOOLEAN Directory;                 TRUE if this is a directory
 163  *  USHORT ByteCount;                  = 0
 164  *
 165  * The following SMBs may follow SMB_COM_NT_CREATE_ANDX:
 166  *
 167  *    SMB_COM_READ    SMB_COM_READ_ANDX
 168  *    SMB_COM_IOCTL
 169  */
 170 smb_sdrc_t
 171 smb_pre_nt_create_andx(smb_request_t *sr)
 172 {
 173         struct open_param *op = &sr->arg.open;
 174         uint8_t SecurityFlags;
 175         uint32_t ImpersonationLevel;
 176         uint16_t NameLength;
 177         int rc;
 178 
 179         bzero(op, sizeof (sr->arg.open));
 180 
 181         rc = smbsr_decode_vwv(sr, "5.wlllqlllllb",
 182             &NameLength,
 183             &op->nt_flags,
 184             &op->rootdirfid,
 185             &op->desired_access,
 186             &op->dsize,
 187             &op->dattr,
 188             &op->share_access,
 189             &op->create_disposition,
 190             &op->create_options,
 191             &ImpersonationLevel,
 192             &SecurityFlags);
 193 
 194         if (rc == 0) {
 195                 if (NameLength == 0) {
 196                         op->fqi.fq_path.pn_path = "\\";
 197                 } else if (NameLength >= SMB_MAXPATHLEN) {
 198                         smbsr_error(sr, NT_STATUS_OBJECT_NAME_INVALID,
 199                             ERRDOS, ERROR_PATH_NOT_FOUND);
 200                         rc = -1;
 201                 } else {
 202                         rc = smbsr_decode_data(sr, "%#u", sr, NameLength,
 203                             &op->fqi.fq_path.pn_path);
 204                 }
 205         }
 206 
 207         op->op_oplock_level = SMB_OPLOCK_NONE;
 208         if (op->nt_flags & NT_CREATE_FLAG_REQUEST_OPLOCK) {
 209                 if (op->nt_flags & NT_CREATE_FLAG_REQUEST_OPBATCH)
 210                         op->op_oplock_level = SMB_OPLOCK_BATCH;
 211                 else
 212                         op->op_oplock_level = SMB_OPLOCK_EXCLUSIVE;
 213         }
 214 
 215         DTRACE_SMB_2(op__NtCreateX__start, smb_request_t *, sr,
 216             struct open_param *, op);
 217 
 218         return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
 219 }
 220 
 221 void
 222 smb_post_nt_create_andx(smb_request_t *sr)
 223 {
 224         DTRACE_SMB_1(op__NtCreateX__done, smb_request_t *, sr);
 225 
 226         if (sr->arg.open.dir != NULL) {
 227                 smb_ofile_release(sr->arg.open.dir);
 228                 sr->arg.open.dir = NULL;
 229         }
 230 }
 231 
 232 /*
 233  * A lot like smb_nt_transact_create
 234  */
 235 smb_sdrc_t
 236 smb_com_nt_create_andx(struct smb_request *sr)
 237 {
 238         struct open_param       *op = &sr->arg.open;
 239         smb_attr_t              *ap = &op->fqi.fq_fattr;
 240         smb_ofile_t             *of;
 241         int                     rc;
 242         uint8_t                 DirFlag;
 243         uint32_t                status;
 244 
 245         if (op->create_options & ~SMB_NTCREATE_VALID_OPTIONS) {
 246                 smbsr_error(sr, NT_STATUS_INVALID_PARAMETER,
 247                     ERRDOS, ERROR_INVALID_PARAMETER);
 248                 return (SDRC_ERROR);
 249         }
 250 
 251         if (op->create_options & FILE_OPEN_BY_FILE_ID) {
 252                 smbsr_error(sr, NT_STATUS_NOT_SUPPORTED,
 253                     ERRDOS, ERROR_NOT_SUPPORTED);
 254                 return (SDRC_ERROR);
 255         }
 256 
 257         if ((op->create_options & FILE_DELETE_ON_CLOSE) &&
 258             !(op->desired_access & DELETE)) {
 259                 smbsr_error(sr, NT_STATUS_INVALID_PARAMETER,
 260                     ERRDOS, ERRbadaccess);
 261                 return (SDRC_ERROR);
 262         }
 263 
 264         if (op->create_disposition > FILE_MAXIMUM_DISPOSITION) {
 265                 smbsr_error(sr, NT_STATUS_INVALID_PARAMETER,
 266                     ERRDOS, ERRbadaccess);
 267                 return (SDRC_ERROR);
 268         }
 269 
 270         if (op->dattr & FILE_FLAG_WRITE_THROUGH)
 271                 op->create_options |= FILE_WRITE_THROUGH;
 272 
 273         if (op->dattr & FILE_FLAG_DELETE_ON_CLOSE)
 274                 op->create_options |= FILE_DELETE_ON_CLOSE;
 275 
 276         if (op->dattr & FILE_FLAG_BACKUP_SEMANTICS)
 277                 op->create_options |= FILE_OPEN_FOR_BACKUP_INTENT;
 278 
 279         if (op->create_options & FILE_OPEN_FOR_BACKUP_INTENT)
 280                 sr->user_cr = smb_user_getprivcred(sr->uid_user);
 281 
 282         if (op->rootdirfid == 0) {
 283                 op->fqi.fq_dnode = sr->tid_tree->t_snode;
 284         } else {
 285                 op->dir = smb_ofile_lookup_by_fid(sr, (uint16_t)op->rootdirfid);
 286                 if (op->dir == NULL) {
 287                         smbsr_error(sr, NT_STATUS_INVALID_HANDLE,
 288                             ERRDOS, ERRbadfid);
 289                         return (SDRC_ERROR);
 290                 }
 291                 op->fqi.fq_dnode = op->dir->f_node;
 292         }
 293 
 294         op->op_oplock_levelII = B_TRUE;
 295 
 296         status = smb_common_open(sr);
 297         if (status != NT_STATUS_SUCCESS) {
 298                 smbsr_status(sr, status, 0, 0);
 299                 return (SDRC_ERROR);
 300         }
 301 
 302         /*
 303          * NB: after the above smb_common_open() success,
 304          * we have a handle allocated (sr->fid_ofile).
 305          * If we don't return success, we must close it.
 306          */
 307         of = sr->fid_ofile;
 308 
 309         switch (sr->tid_tree->t_res_type & STYPE_MASK) {
 310         case STYPE_DISKTREE:
 311         case STYPE_PRINTQ:
 312                 if (op->create_options & FILE_DELETE_ON_CLOSE)
 313                         smb_ofile_set_delete_on_close(of);
 314                 DirFlag = smb_node_is_dir(of->f_node) ? 1 : 0;
 315                 break;
 316 
 317         case STYPE_IPC:
 318                 DirFlag = 0;
 319                 break;
 320 
 321         default:
 322                 smbsr_error(sr, NT_STATUS_INVALID_DEVICE_REQUEST,
 323                     ERRDOS, ERROR_INVALID_FUNCTION);
 324                 goto errout;
 325         }
 326 
 327         if ((op->nt_flags & NT_CREATE_FLAG_EXTENDED_RESPONSE) != 0 &&
 328             smb_nt_create_enable_extended_response != 0) {
 329                 uint32_t MaxAccess = 0;
 330                 if (of->f_node != NULL) {
 331                         smb_fsop_eaccess(sr, of->f_cr, of->f_node, &MaxAccess);
 332                 }
 333                 MaxAccess |= of->f_granted_access;
 334 
 335                 /*
 336                  * Here is a really ugly protocol wart in SMB1:
 337                  *
 338                  * [MS-SMB] Sec. 2.2.4.9.2: Windows-based SMB servers
 339                  * send 50 (0x32) words in the extended response although
 340                  * they set the WordCount field to 0x2A.
 341                  *
 342                  * In other words, THEY LIE!  We really do need to encode
 343                  * 50 words here, but lie and say we encoded 42 words.
 344                  * This means we can't use smbsr_encode_result() to
 345                  * build this response, because the rules it breaks
 346                  * would cause errors in smbsr_check_result().
 347                  */
 348                 sr->smb_wct = 50; /* real word count */
 349                 sr->smb_bcc = 0;
 350                 rc = smb_mbc_encodef(&sr->reply,
 351                     "bb.wbwlTTTTlqqwwb16.qllw",
 352                     42,         /* fake word count (b) */
 353                     sr->andx_com,            /* (b.) */
 354                     0x87,       /* andx offset     (w) */
 355                     op->op_oplock_level,     /* (b) */
 356                     sr->smb_fid,             /* (w) */
 357                     op->action_taken,                /* (l) */
 358                     &ap->sa_crtime,              /* (T) */
 359                     &ap->sa_vattr.va_atime,      /* (T) */
 360                     &ap->sa_vattr.va_mtime,      /* (T) */
 361                     &ap->sa_vattr.va_ctime,      /* (T) */
 362                     op->dattr & FILE_ATTRIBUTE_MASK, /* (l) */
 363                     ap->sa_allocsz,          /* (q) */
 364                     ap->sa_vattr.va_size,    /* (q) */
 365                     op->ftype,                       /* (w) */
 366                     op->devstate,            /* (w) */
 367                     DirFlag,                    /* (b) */
 368                     /* volume guid                (16.) */
 369                     op->fileid,                      /* (q) */
 370                     MaxAccess,                  /* (l) */
 371                     0,          /* guest access    (l) */
 372                     0);         /* byte count      (w) */
 373         } else {
 374                 rc = smbsr_encode_result(
 375                     sr, 34, 0, "bb.wbwlTTTTlqqwwbw",
 376                     34,         /* word count      (b) */
 377                     sr->andx_com,            /* (b.) */
 378                     0x67,       /* andx offset     (w) */
 379                     op->op_oplock_level,     /* (b) */
 380                     sr->smb_fid,             /* (w) */
 381                     op->action_taken,                /* (l) */
 382                     &ap->sa_crtime,              /* (T) */
 383                     &ap->sa_vattr.va_atime,      /* (T) */
 384                     &ap->sa_vattr.va_mtime,      /* (T) */
 385                     &ap->sa_vattr.va_ctime,      /* (T) */
 386                     op->dattr & FILE_ATTRIBUTE_MASK, /* (l) */
 387                     ap->sa_allocsz,          /* (q) */
 388                     ap->sa_vattr.va_size,    /* (q) */
 389                     op->ftype,                       /* (w) */
 390                     op->devstate,            /* (w) */
 391                     DirFlag,                    /* (b) */
 392                     0);         /* byte count      (w) */
 393         }
 394 
 395         if (rc == 0)
 396                 return (SDRC_SUCCESS);
 397 
 398 errout:
 399         smb_ofile_close(of, 0);
 400         return (SDRC_ERROR);
 401 }