a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * This file and its contents are supplied under the terms of the
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * Common Development and Distribution License ("CDDL"), version 1.0.
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * You may only use this file in accordance with the terms of version
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * 1.0 of the CDDL.
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * A full copy of the text of the CDDL should have accompanied this
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * source. A copy of the CDDL is also available via the Internet at
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * Dispatch function for SMB2_CREATE
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * [MS-SMB2] 2.2.13
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * Some flags used locally to keep track of which Create Context
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * names have been provided and/or requested.
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross /* Elements we may see in the request. */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross /* Elements we my place in the response */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross mbuf_chain_t *, smb2_create_ctx_elem_t *, uint32_t);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Rossstatic void smb2_free_create_ctx(smb2_create_ctx_t *);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * Paranoia. This will set sr->fid_ofile, so
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * if we already have one, release it now.
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * SMB2 Create request
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * We're normally positioned at the path name now,
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * but there could be some padding before it.
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross (void) smb_mbc_decodef(&sr->smb_data, "#.", skip);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * Get the path name
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * ImpersonationLevel (spec. says ignore)
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * SmbCreateFlags (spec. says ignore)
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross if ((op->create_options & FILE_DELETE_ON_CLOSE) &&
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross if (op->create_disposition > FILE_MAXIMUM_DISPOSITION) {
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross op->create_options |= FILE_OPEN_FOR_BACKUP_INTENT;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross if (op->create_options & FILE_OPEN_FOR_BACKUP_INTENT)
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross sr->user_cr = smb_user_getprivcred(sr->uid_user);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * If there is a "Create Context" payload, decode it.
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * This may carry things like a security descriptor,
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * extended attributes, etc. to be used in create.
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * The create ctx buffer must start after the headers
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * and file name, and must be 8-byte aligned.
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross sr->smb2_cmd_hdr + CreateCtxOffset, CreateCtxLength);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross status = smb2_decode_create_ctx(&cc_mbc, &cctx);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross rc = smb_mbc_decodef(&cce->cce_mbc, "q", &op->dsize);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * Support for opening "Previous Versions".
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * [MS-SMB2] 2.2.13.2.7 Data is an NT time.
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * The real open call. Note: this gets attributes into
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * op->fqi.fq_fattr (SMB_AT_ALL). We need those below.
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * Convert the negotiate Oplock level back into
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * SMB2 encoding form.
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * NB: after the above smb_common_open() success,
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * we have a handle allocated (sr->fid_ofile).
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * If we don't return success, we must close it.
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * Using sr->smb_fid as the file handle for now,
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * though it could later be something larger,
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * (16 bytes) similar to an NFSv4 open handle.
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross switch (sr->tid_tree->t_res_type & STYPE_MASK) {
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * Build the Create Context to return; first the
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * per-element parts, then the aggregated buffer.
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * No response for these:
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * CCTX_EA_BUFFER
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * CCTX_SD_BUFFER
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * CCTX_ALLOCATION_SIZE
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * CCTX_TIMEWARP_TOKEN
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * We don't handle these yet.
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * CCTX_DH_REQUEST
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * CCTX_DH_RECONNECT
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * CCTX_REQUEST_LEASE
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross smb_fsop_eaccess(sr, of->f_cr, of->f_node, &MaxAccess);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross if ((cctx.cc_in_flags & CCTX_QUERY_ON_DISK_ID) != 0 &&
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross /* reserved (16 bytes) .15. */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross status = smb2_encode_create_ctx(&sr->raw_data, &cctx);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * SMB2 Create reply
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross "wb.lTTTTqqllqqll",
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross 0, /* CreateCtxOffset l */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross 0); /* CreateCtxLength l */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross CreateCtxOffset = sr->reply.chain_offset - sr->smb2_reply_hdr;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * Overwrite CreateCtxOffset, CreateCtxLength, pad
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * Decode an SMB2 Create Context buffer into our internal form.
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * No policy decisions about what's supported here, just decode.
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Rosssmb2_decode_create_ctx(mbuf_chain_t *in_mbc, smb2_create_ctx_t *cc)
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross /* reserved .. */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * The Create Context "name", per [MS-SMB] 2.2.13.2
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * They're defined as network-order integers for our
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * switch below. We don't have routines to decode
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * native order, so read as char[4] then ntohl.
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * NB: in SMB3, some of these are 8 bytes.
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross if ((top_offset + name_off) < in_mbc->chain_offset)
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross rc = smb_mbc_decodef(&name_mbc, "4c", &cc_name);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross case SMB2_CREATE_DURABLE_HANDLE_REQUEST: /* ("DHnQ") */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross case SMB2_CREATE_DURABLE_HANDLE_RECONNECT: /* ("DHnC") */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross case SMB2_CREATE_ALLOCATION_SIZE: /* ("AISi") */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross case SMB2_CREATE_QUERY_MAXIMAL_ACCESS_REQ: /* ("MxAc") */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross /* no input data for this */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross case SMB2_CREATE_QUERY_ON_DISK_ID: /* ("QFid") */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross /* no input data for this */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * Unknown create context values are normal, and
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * should be ignored. However, in debug mode,
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * let's log them so we know which ones we're
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * not handling (and may want to add).
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross cmn_err(CE_NOTE, "unknown create context ID 0x%x",
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross if ((top_offset + data_off) < in_mbc->chain_offset)
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross /* Normal loop termination */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross if ((top_offset + next_off) < in_mbc->chain_offset)
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross if ((top_offset + next_off) > in_mbc->max_bytes)
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * Encode an SMB2 Create Context buffer from our internal form.
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross/* ARGSUSED */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Rosssmb2_encode_create_ctx(mbuf_chain_t *mbc, smb2_create_ctx_t *cc)
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Rosssmb2_encode_create_ctx_elem(mbuf_chain_t *out_mbc,
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross /* as above */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * This is the header, per [MS-SMB2] 2.2.13.2
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * Sorry about the fixed offsets. We know we'll
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * layout the data part as [name, payload] and
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * name is a fixed length, so this easy.
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * The final layout looks like this:
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * a: this header (16 bytes)
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * b: the name (4 bytes, 4 pad)
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * c: the payload (variable)
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * Note that "Next elem." is filled in later.
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross 0, /* Next offset l */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross 0, /* Reserved w */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * Now the "name" and payload.