a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross/*
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 *
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 * http://www.illumos.org/license/CDDL.
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross/*
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross/*
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * Dispatch function for SMB2_CREATE
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * [MS-SMB2] 2.2.13
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross#include <smbsrv/smb2_kproto.h>
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross#include <smbsrv/smb_fsops.h>
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross/*
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * Some flags used locally to keep track of which Create Context
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * names have been provided and/or requested.
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross#define CCTX_EA_BUFFER 1
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross#define CCTX_SD_BUFFER 2
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross#define CCTX_DH_REQUEST 4
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross#define CCTX_DH_RECONNECT 8
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross#define CCTX_ALLOCATION_SIZE 0x10
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross#define CCTX_QUERY_MAX_ACCESS 0x20
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross#define CCTX_TIMEWARP_TOKEN 0x40
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross#define CCTX_QUERY_ON_DISK_ID 0x80
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross#define CCTX_REQUEST_LEASE 0x100
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Rosstypedef struct smb2_create_ctx_elem {
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross uint32_t cce_len;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross mbuf_chain_t cce_mbc;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross} smb2_create_ctx_elem_t;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Rosstypedef struct smb2_create_ctx {
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross uint_t cc_in_flags; /* CCTX_... */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross uint_t cc_out_flags; /* CCTX_... */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross /* Elements we may see in the request. */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross smb2_create_ctx_elem_t cc_in_ext_attr;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross smb2_create_ctx_elem_t cc_in_sec_desc;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross smb2_create_ctx_elem_t cc_in_dh_request;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross smb2_create_ctx_elem_t cc_in_dh_reconnect;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross smb2_create_ctx_elem_t cc_in_alloc_size;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross smb2_create_ctx_elem_t cc_in_time_warp;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross smb2_create_ctx_elem_t cc_in_req_lease;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross /* Elements we my place in the response */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross smb2_create_ctx_elem_t cc_out_max_access;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross smb2_create_ctx_elem_t cc_out_file_id;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross} smb2_create_ctx_t;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Rossstatic uint32_t smb2_decode_create_ctx(
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross mbuf_chain_t *, smb2_create_ctx_t *);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Rossstatic uint32_t smb2_encode_create_ctx(
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross mbuf_chain_t *, smb2_create_ctx_t *);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Rossstatic int smb2_encode_create_ctx_elem(
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
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Rosssmb_sdrc_t
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Rosssmb2_create(smb_request_t *sr)
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross{
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross smb_attr_t *attr;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross smb2_create_ctx_elem_t *cce;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross smb2_create_ctx_t cctx;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross mbuf_chain_t cc_mbc;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross smb_arg_open_t *op = &sr->arg.open;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross smb_ofile_t *of = NULL;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross uint16_t StructSize;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross uint8_t SecurityFlags;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross uint8_t OplockLevel;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross uint32_t ImpersonationLevel;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross uint64_t SmbCreateFlags;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross uint64_t Reserved4;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross uint16_t NameOffset;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross uint16_t NameLength;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross uint32_t CreateCtxOffset;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross uint32_t CreateCtxLength;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross smb2fid_t smb2fid;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross uint32_t status;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross int skip;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross int rc = 0;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross bzero(&cctx, sizeof (cctx));
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross bzero(&cc_mbc, sizeof (cc_mbc));
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross /*
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * Paranoia. This will set sr->fid_ofile, so
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * if we already have one, release it now.
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross if (sr->fid_ofile != NULL) {
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross smb_ofile_request_complete(sr->fid_ofile);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross smb_ofile_release(sr->fid_ofile);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross sr->fid_ofile = NULL;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross }
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross /*
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * SMB2 Create request
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross rc = smb_mbc_decodef(
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross &sr->smb_data, "wbblqqlllllwwll",
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross &StructSize, /* w */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross &SecurityFlags, /* b */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross &OplockLevel, /* b */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross &ImpersonationLevel, /* l */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross &SmbCreateFlags, /* q */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross &Reserved4, /* q */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross &op->desired_access, /* l */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross &op->dattr, /* l */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross &op->share_access, /* l */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross &op->create_disposition, /* l */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross &op->create_options, /* l */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross &NameOffset, /* w */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross &NameLength, /* w */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross &CreateCtxOffset, /* l */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross &CreateCtxLength); /* l */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross if (rc != 0 || StructSize != 57)
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross return (SDRC_ERROR);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross /*
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * We're normally positioned at the path name now,
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * but there could be some padding before it.
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross skip = (NameOffset + sr->smb2_cmd_hdr) -
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross sr->smb_data.chain_offset;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross if (skip < 0) {
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross status = NT_STATUS_OBJECT_PATH_INVALID;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross goto errout;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross }
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross if (skip > 0)
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross (void) smb_mbc_decodef(&sr->smb_data, "#.", skip);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross /*
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * Get the path name
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross if (NameLength >= SMB_MAXPATHLEN) {
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross status = NT_STATUS_OBJECT_PATH_INVALID;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross goto errout;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross }
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross if (NameLength == 0) {
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross op->fqi.fq_path.pn_path = "\\";
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross } else {
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross rc = smb_mbc_decodef(&sr->smb_data, "%#U", sr,
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross NameLength, &op->fqi.fq_path.pn_path);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross if (rc) {
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross status = NT_STATUS_OBJECT_PATH_INVALID;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross goto errout;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross }
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross }
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross op->fqi.fq_dnode = sr->tid_tree->t_snode;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross switch (OplockLevel) {
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross case SMB2_OPLOCK_LEVEL_NONE:
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross op->op_oplock_level = SMB_OPLOCK_NONE;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross break;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross case SMB2_OPLOCK_LEVEL_II:
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross op->op_oplock_level = SMB_OPLOCK_LEVEL_II;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross break;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross case SMB2_OPLOCK_LEVEL_EXCLUSIVE:
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross op->op_oplock_level = SMB_OPLOCK_EXCLUSIVE;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross break;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross case SMB2_OPLOCK_LEVEL_BATCH:
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross op->op_oplock_level = SMB_OPLOCK_BATCH;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross break;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross case SMB2_OPLOCK_LEVEL_LEASE:
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross status = NT_STATUS_INVALID_PARAMETER;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross goto errout;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross }
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross op->op_oplock_levelII = B_TRUE;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross /*
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * ImpersonationLevel (spec. says ignore)
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * SmbCreateFlags (spec. says ignore)
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross if ((op->create_options & FILE_DELETE_ON_CLOSE) &&
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross !(op->desired_access & DELETE)) {
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross status = NT_STATUS_INVALID_PARAMETER;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross goto errout;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross }
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross if (op->create_disposition > FILE_MAXIMUM_DISPOSITION) {
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross status = NT_STATUS_INVALID_PARAMETER;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross goto errout;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross }
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross if (op->dattr & FILE_FLAG_WRITE_THROUGH)
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross op->create_options |= FILE_WRITE_THROUGH;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross if (op->dattr & FILE_FLAG_DELETE_ON_CLOSE)
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross op->create_options |= FILE_DELETE_ON_CLOSE;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross if (op->dattr & FILE_FLAG_BACKUP_SEMANTICS)
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
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross /*
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 *
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * The create ctx buffer must start after the headers
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * and file name, and must be 8-byte aligned.
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross if (CreateCtxLength != 0) {
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross if ((CreateCtxOffset & 7) != 0 ||
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross (CreateCtxOffset + sr->smb2_cmd_hdr) <
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross sr->smb_data.chain_offset) {
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross status = NT_STATUS_INVALID_PARAMETER;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross goto errout;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross }
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross rc = MBC_SHADOW_CHAIN(&cc_mbc, &sr->smb_data,
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross sr->smb2_cmd_hdr + CreateCtxOffset, CreateCtxLength);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross if (rc) {
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross status = NT_STATUS_INVALID_PARAMETER;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross goto errout;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross }
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross status = smb2_decode_create_ctx(&cc_mbc, &cctx);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross if (status)
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross goto errout;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross if (cctx.cc_in_flags & CCTX_EA_BUFFER) {
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross status = NT_STATUS_EAS_NOT_SUPPORTED;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross goto errout;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross }
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross if (cctx.cc_in_flags & CCTX_SD_BUFFER) {
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross smb_sd_t sd;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross cce = &cctx.cc_in_sec_desc;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross status = smb_decode_sd(
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross &cce->cce_mbc, &sd);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross if (status)
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross goto errout;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross op->sd = kmem_alloc(sizeof (sd), KM_SLEEP);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross *op->sd = sd;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross }
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross if (cctx.cc_in_flags & CCTX_ALLOCATION_SIZE) {
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross cce = &cctx.cc_in_alloc_size;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross rc = smb_mbc_decodef(&cce->cce_mbc, "q", &op->dsize);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross if (rc) {
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross status = NT_STATUS_INVALID_PARAMETER;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross goto errout;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross }
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross }
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross /*
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * Support for opening "Previous Versions".
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * [MS-SMB2] 2.2.13.2.7 Data is an NT time.
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross if (cctx.cc_in_flags & CCTX_TIMEWARP_TOKEN) {
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross uint64_t timewarp;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross cce = &cctx.cc_in_time_warp;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross status = smb_mbc_decodef(&cce->cce_mbc,
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross "q", &timewarp);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross if (status)
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross goto errout;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross smb_time_nt_to_unix(timewarp, &op->timewarp);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross op->create_timewarp = B_TRUE;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross }
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross }
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross /*
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 */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross status = smb_common_open(sr);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross if (status != NT_STATUS_SUCCESS)
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross goto errout;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross attr = &op->fqi.fq_fattr;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross /*
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * Convert the negotiate Oplock level back into
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * SMB2 encoding form.
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross switch (op->op_oplock_level) {
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross default:
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross case SMB_OPLOCK_NONE:
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross OplockLevel = SMB2_OPLOCK_LEVEL_NONE;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross break;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross case SMB_OPLOCK_LEVEL_II:
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross OplockLevel = SMB2_OPLOCK_LEVEL_II;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross break;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross case SMB_OPLOCK_EXCLUSIVE:
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross OplockLevel = SMB2_OPLOCK_LEVEL_EXCLUSIVE;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross break;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross case SMB_OPLOCK_BATCH:
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross OplockLevel = SMB2_OPLOCK_LEVEL_BATCH;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross break;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross }
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross /*
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 *
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 */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross of = sr->fid_ofile;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross smb2fid.persistent = 0;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross smb2fid.temporal = sr->smb_fid;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross switch (sr->tid_tree->t_res_type & STYPE_MASK) {
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross case STYPE_DISKTREE:
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross case STYPE_PRINTQ:
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross if (op->create_options & FILE_DELETE_ON_CLOSE)
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross smb_ofile_set_delete_on_close(of);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross break;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross }
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross /*
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * Build the Create Context to return; first the
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * per-element parts, then the aggregated buffer.
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross *
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 *
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 */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross if (cctx.cc_in_flags & CCTX_QUERY_MAX_ACCESS) {
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross cce = &cctx.cc_out_max_access;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross uint32_t MaxAccess = 0;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross if (of->f_node != NULL) {
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross smb_fsop_eaccess(sr, of->f_cr, of->f_node, &MaxAccess);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross }
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross MaxAccess |= of->f_granted_access;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross cce->cce_len = 8;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross cce->cce_mbc.max_bytes = 8;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross (void) smb_mbc_encodef(&cce->cce_mbc,
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross "ll", 0, MaxAccess);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross cctx.cc_out_flags |= CCTX_QUERY_MAX_ACCESS;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross }
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross if ((cctx.cc_in_flags & CCTX_QUERY_ON_DISK_ID) != 0 &&
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross of->f_node != NULL) {
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross cce = &cctx.cc_out_file_id;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross fsid_t fsid;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross fsid = SMB_NODE_FSID(of->f_node);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross cce->cce_len = 32;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross cce->cce_mbc.max_bytes = 32;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross (void) smb_mbc_encodef(
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross &cce->cce_mbc, "qll.15.",
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross op->fileid, /* q */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross fsid.val[0], /* l */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross fsid.val[1]); /* l */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross /* reserved (16 bytes) .15. */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross cctx.cc_out_flags |= CCTX_QUERY_ON_DISK_ID;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross }
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross if (cctx.cc_out_flags) {
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross sr->raw_data.max_bytes = smb2_max_trans;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross status = smb2_encode_create_ctx(&sr->raw_data, &cctx);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross if (status)
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross goto errout;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross }
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross /*
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * SMB2 Create reply
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross rc = smb_mbc_encodef(
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross &sr->reply,
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross "wb.lTTTTqqllqqll",
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross 89, /* StructSize */ /* w */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross OplockLevel, /* b */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross op->action_taken, /* l */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross &attr->sa_crtime, /* T */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross &attr->sa_vattr.va_atime, /* T */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross &attr->sa_vattr.va_mtime, /* T */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross &attr->sa_vattr.va_ctime, /* T */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross attr->sa_allocsz, /* q */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross attr->sa_vattr.va_size, /* q */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross attr->sa_dosattr, /* l */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross 0, /* reserved2 */ /* l */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross smb2fid.persistent, /* q */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross smb2fid.temporal, /* q */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross 0, /* CreateCtxOffset l */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross 0); /* CreateCtxLength l */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross if (rc != 0) {
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross status = NT_STATUS_UNSUCCESSFUL;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross goto errout;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross }
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross CreateCtxOffset = sr->reply.chain_offset - sr->smb2_reply_hdr;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross CreateCtxLength = MBC_LENGTH(&sr->raw_data);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross if (CreateCtxLength != 0) {
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross /*
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * Overwrite CreateCtxOffset, CreateCtxLength, pad
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross sr->reply.chain_offset -= 8;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross rc = smb_mbc_encodef(
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross &sr->reply,
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross "ll#C",
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross CreateCtxOffset, /* l */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross CreateCtxLength, /* l */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross CreateCtxLength, /* # */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross &sr->raw_data); /* C */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross if (rc != 0) {
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross status = NT_STATUS_UNSUCCESSFUL;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross goto errout;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross }
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross } else {
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross (void) smb_mbc_encodef(&sr->reply, ".");
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross }
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross return (SDRC_SUCCESS);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Rosserrout:
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross if (of != NULL)
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross smb_ofile_close(of, 0);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross if (cctx.cc_out_flags)
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross smb2_free_create_ctx(&cctx);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross smb2sr_put_error(sr, status);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross return (SDRC_SUCCESS);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross}
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross/*
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 Ross */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Rossstatic uint32_t
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Rosssmb2_decode_create_ctx(mbuf_chain_t *in_mbc, smb2_create_ctx_t *cc)
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross{
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross smb2_create_ctx_elem_t *cce;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross mbuf_chain_t name_mbc;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross union {
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross uint32_t i;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross char ch[4];
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross } cc_name;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross uint32_t status;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross int32_t next_off;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross uint32_t data_len;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross uint16_t data_off;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross uint16_t name_off;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross uint16_t name_len;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross int top_offset;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross int rc;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross status = NT_STATUS_INVALID_PARAMETER;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross for (;;) {
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross cce = NULL;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross top_offset = in_mbc->chain_offset;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross rc = smb_mbc_decodef(
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross in_mbc,
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross "lww..wl",
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross &next_off, /* l */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross &name_off, /* w */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross &name_len, /* w */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross /* reserved .. */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross &data_off, /* w */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross &data_len); /* l */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross if (rc)
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross break;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross /*
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 */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross if ((top_offset + name_off) < in_mbc->chain_offset)
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross break;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross rc = MBC_SHADOW_CHAIN(&name_mbc, in_mbc,
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross top_offset + name_off, name_len);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross if (rc)
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross break;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross rc = smb_mbc_decodef(&name_mbc, "4c", &cc_name);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross if (rc)
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross break;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross cc_name.i = ntohl(cc_name.i);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross switch (cc_name.i) {
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross case SMB2_CREATE_EA_BUFFER: /* ("ExtA") */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross cc->cc_in_flags |= CCTX_EA_BUFFER;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross cce = &cc->cc_in_ext_attr;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross break;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross case SMB2_CREATE_SD_BUFFER: /* ("SecD") */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross cc->cc_in_flags |= CCTX_SD_BUFFER;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross cce = &cc->cc_in_sec_desc;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross break;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross case SMB2_CREATE_DURABLE_HANDLE_REQUEST: /* ("DHnQ") */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross cc->cc_in_flags |= CCTX_DH_REQUEST;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross cce = &cc->cc_in_dh_request;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross break;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross case SMB2_CREATE_DURABLE_HANDLE_RECONNECT: /* ("DHnC") */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross cc->cc_in_flags |= CCTX_DH_RECONNECT;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross cce = &cc->cc_in_dh_reconnect;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross break;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross case SMB2_CREATE_ALLOCATION_SIZE: /* ("AISi") */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross cc->cc_in_flags |= CCTX_ALLOCATION_SIZE;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross cce = &cc->cc_in_alloc_size;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross break;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross case SMB2_CREATE_QUERY_MAXIMAL_ACCESS_REQ: /* ("MxAc") */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross cc->cc_in_flags |= CCTX_QUERY_MAX_ACCESS;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross /* no input data for this */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross break;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross case SMB2_CREATE_TIMEWARP_TOKEN: /* ("TWrp") */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross cc->cc_in_flags |= CCTX_TIMEWARP_TOKEN;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross cce = &cc->cc_in_time_warp;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross break;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross case SMB2_CREATE_QUERY_ON_DISK_ID: /* ("QFid") */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross cc->cc_in_flags |= CCTX_QUERY_ON_DISK_ID;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross /* no input data for this */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross break;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross case SMB2_CREATE_REQUEST_LEASE: /* ("RqLs") */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross cc->cc_in_flags |= CCTX_REQUEST_LEASE;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross cce = &cc->cc_in_req_lease;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross break;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross default:
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross /*
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 */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross#ifdef DEBUG
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross cmn_err(CE_NOTE, "unknown create context ID 0x%x",
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross cc_name.i);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross#endif
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross cce = NULL;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross break;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross }
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross if (cce != NULL && data_len != 0) {
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross if ((data_off & 7) != 0)
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross break;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross if ((top_offset + data_off) < in_mbc->chain_offset)
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross break;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross rc = MBC_SHADOW_CHAIN(&cce->cce_mbc, in_mbc,
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross top_offset + data_off, data_len);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross if (rc)
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross break;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross cce->cce_len = data_len;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross }
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross if (next_off == 0) {
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross /* Normal loop termination */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross status = 0;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross break;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross }
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross if ((next_off & 7) != 0)
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross break;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross if ((top_offset + next_off) < in_mbc->chain_offset)
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross break;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross if ((top_offset + next_off) > in_mbc->max_bytes)
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross break;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross in_mbc->chain_offset = top_offset + next_off;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross }
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross return (status);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross}
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross/*
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * Encode an SMB2 Create Context buffer from our internal form.
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross/* ARGSUSED */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Rossstatic uint32_t
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Rosssmb2_encode_create_ctx(mbuf_chain_t *mbc, smb2_create_ctx_t *cc)
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross{
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross smb2_create_ctx_elem_t *cce;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross int last_top = -1;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross int rc;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross if (cc->cc_out_flags & CCTX_QUERY_MAX_ACCESS) {
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross cce = &cc->cc_out_max_access;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross last_top = mbc->chain_offset;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross rc = smb2_encode_create_ctx_elem(mbc, cce,
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross SMB2_CREATE_QUERY_MAXIMAL_ACCESS_REQ);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross if (rc)
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross return (NT_STATUS_INTERNAL_ERROR);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross (void) smb_mbc_poke(mbc, last_top, "l",
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross mbc->chain_offset - last_top);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross }
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross if (cc->cc_out_flags & CCTX_QUERY_ON_DISK_ID) {
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross cce = &cc->cc_out_file_id;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross last_top = mbc->chain_offset;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross rc = smb2_encode_create_ctx_elem(mbc, cce,
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross SMB2_CREATE_QUERY_ON_DISK_ID);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross if (rc)
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross return (NT_STATUS_INTERNAL_ERROR);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross (void) smb_mbc_poke(mbc, last_top, "l",
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross mbc->chain_offset - last_top);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross }
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross if (last_top >= 0)
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross (void) smb_mbc_poke(mbc, last_top, "l", 0);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross return (0);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross}
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Rossstatic int
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Rosssmb2_encode_create_ctx_elem(mbuf_chain_t *out_mbc,
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross smb2_create_ctx_elem_t *cce, uint32_t id)
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross{
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross union {
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross uint32_t i;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross char ch[4];
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross } cc_name;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross int rc;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross /* as above */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross cc_name.i = htonl(id);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross /*
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 *
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * Note that "Next elem." is filled in later.
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross rc = smb_mbc_encodef(
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross out_mbc, "lwwwwl",
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross 0, /* Next offset l */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross 16, /* NameOffset w */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross 4, /* NameLength w */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross 0, /* Reserved w */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross 24, /* DataOffset w */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross cce->cce_len); /* l */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross if (rc)
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross return (rc);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross /*
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * Now the "name" and payload.
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross rc = smb_mbc_encodef(
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross out_mbc, "4c4.#C",
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross cc_name.ch, /* 4c4. */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross cce->cce_len, /* # */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross &cce->cce_mbc); /* C */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross return (rc);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross}
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Rossstatic void
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Rosssmb2_free_create_ctx(smb2_create_ctx_t *cc)
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross{
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross smb2_create_ctx_elem_t *cce;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross if (cc->cc_out_flags & CCTX_QUERY_MAX_ACCESS) {
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross cce = &cc->cc_out_max_access;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross MBC_FLUSH(&cce->cce_mbc);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross }
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross if (cc->cc_out_flags & CCTX_QUERY_ON_DISK_ID) {
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross cce = &cc->cc_out_file_id;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross MBC_FLUSH(&cce->cce_mbc);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross }
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross}