Example #1
0
/*
 * Common create file function.  The file is opened in compatibility
 * mode with read/write access.
 */
uint32_t
smb_common_create(smb_request_t *sr)
{
	struct open_param *op = &sr->arg.open;
	uint32_t status;

	if ((op->mtime.tv_sec != 0) && (op->mtime.tv_sec != UINT_MAX))
		op->mtime.tv_sec = smb_time_local_to_gmt(sr, op->mtime.tv_sec);
	op->mtime.tv_nsec = 0;
	op->dsize = 0;
	op->omode = SMB_DA_ACCESS_READ_WRITE | SMB_DA_SHARE_COMPATIBILITY;
	op->desired_access = smb_omode_to_amask(op->omode);
	op->share_access = smb_denymode_to_sharemode(op->omode,
	    op->fqi.fq_path.pn_path);

	if (sr->smb_flg & SMB_FLAGS_OPLOCK) {
		if (sr->smb_flg & SMB_FLAGS_OPLOCK_NOTIFY_ANY)
			op->op_oplock_level = SMB_OPLOCK_BATCH;
		else
			op->op_oplock_level = SMB_OPLOCK_EXCLUSIVE;
	} else {
		op->op_oplock_level = SMB_OPLOCK_NONE;
	}
	op->op_oplock_levelII = B_FALSE;

	status = smb_common_open(sr);

	if (op->op_oplock_level == SMB_OPLOCK_NONE) {
		sr->smb_flg &=
		    ~(SMB_FLAGS_OPLOCK | SMB_FLAGS_OPLOCK_NOTIFY_ANY);
	}

	return (status);
}
/*
 * smb_pre_open_andx
 * For compatibility with windows servers, the search attributes
 * specified in the request are ignored.
 */
smb_sdrc_t
smb_pre_open_andx(smb_request_t *sr)
{
	struct open_param *op = &sr->arg.open;
	uint16_t flags;
	uint32_t creation_time;
	uint16_t file_attr, sattr;
	int rc;

	bzero(op, sizeof (sr->arg.open));

	rc = smbsr_decode_vwv(sr, "b.wwwwwlwll4.", &sr->andx_com,
	    &sr->andx_off, &flags, &op->omode, &sattr,
	    &file_attr, &creation_time, &op->ofun, &op->dsize, &op->timeo);

	if (rc == 0) {
		rc = smbsr_decode_data(sr, "%u", sr, &op->fqi.fq_path.pn_path);

		op->dattr = file_attr;

		if (flags & 2)
			op->op_oplock_level = SMB_OPLOCK_EXCLUSIVE;
		else if (flags & 4)
			op->op_oplock_level = SMB_OPLOCK_BATCH;
		else
			op->op_oplock_level = SMB_OPLOCK_NONE;

		if ((creation_time != 0) && (creation_time != UINT_MAX))
			op->crtime.tv_sec =
			    smb_time_local_to_gmt(sr, creation_time);
		op->crtime.tv_nsec = 0;

		op->create_disposition = smb_ofun_to_crdisposition(op->ofun);
	}

	DTRACE_SMB_2(op__OpenX__start, smb_request_t *, sr,
	    struct open_param *, op);

	return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
}
smb_sdrc_t
smb_com_trans2_open2(smb_request_t *sr, smb_xa_t *xa)
{
	struct open_param *op = &sr->arg.open;
	uint32_t	creation_time;
	uint32_t	alloc_size;
	uint16_t	flags;
	uint16_t	file_attr;
	int		rc;

	bzero(op, sizeof (sr->arg.open));

	rc = smb_mbc_decodef(&xa->req_param_mb, "%wwwwlwl10.u",
	    sr, &flags, &op->omode, &op->fqi.fq_sattr, &file_attr,
	    &creation_time, &op->ofun, &alloc_size, &op->fqi.fq_path.pn_path);
	if (rc != 0)
		return (SDRC_ERROR);

	if ((creation_time != 0) && (creation_time != UINT_MAX))
		op->crtime.tv_sec = smb_time_local_to_gmt(sr, creation_time);
	op->crtime.tv_nsec = 0;

	op->dattr = file_attr;
	op->dsize = alloc_size;
	op->create_options = FILE_NON_DIRECTORY_FILE;

	op->desired_access = smb_omode_to_amask(op->omode);
	op->share_access = smb_denymode_to_sharemode(op->omode,
	    op->fqi.fq_path.pn_path);

	op->create_disposition = smb_ofun_to_crdisposition(op->ofun);
	if (op->create_disposition > FILE_MAXIMUM_DISPOSITION)
		op->create_disposition = FILE_CREATE;

	if (op->omode & SMB_DA_WRITE_THROUGH)
		op->create_options |= FILE_WRITE_THROUGH;

	if (sr->smb_flg & SMB_FLAGS_OPLOCK) {
		if (sr->smb_flg & SMB_FLAGS_OPLOCK_NOTIFY_ANY)
			op->op_oplock_level = SMB_OPLOCK_BATCH;
		else
			op->op_oplock_level = SMB_OPLOCK_EXCLUSIVE;
	} else {
		op->op_oplock_level = SMB_OPLOCK_NONE;
	}

	if (smb_common_open(sr) != NT_STATUS_SUCCESS)
		return (SDRC_ERROR);

	if (op->op_oplock_level != SMB_OPLOCK_NONE)
		op->action_taken |= SMB_OACT_LOCK;
	else
		op->action_taken &= ~SMB_OACT_LOCK;

	file_attr = op->dattr & FILE_ATTRIBUTE_MASK;

	if (!STYPE_ISDSK(sr->tid_tree->t_res_type))
		op->dsize = 0;

	(void) smb_mbc_encodef(&xa->rep_param_mb, "wwllwwwwlwl",
	    sr->smb_fid,
	    file_attr,
	    (uint32_t)0,	/* creation time */
	    (uint32_t)op->dsize,
	    op->omode,
	    op->ftype,
	    op->devstate,
	    op->action_taken,
	    op->fileid,
	    (uint16_t)0,	/* EA error offset */
	    (uint32_t)0);	/* EA list length */

	return (SDRC_SUCCESS);
}