Beispiel #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_sdrc_t
smb_com_open(smb_request_t *sr)
{
	struct open_param *op = &sr->arg.open;
	smb_node_t *node;
	smb_attr_t attr;
	uint16_t file_attr;
	int rc;

	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->crtime.tv_sec = op->crtime.tv_nsec = 0;
	op->create_disposition = FILE_OPEN;
	op->create_options = FILE_NON_DIRECTORY_FILE;
	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) {
		sr->smb_flg &=
		    ~(SMB_FLAGS_OPLOCK | SMB_FLAGS_OPLOCK_NOTIFY_ANY);
	}

	if (smb_open_dsize_check && op->dsize > UINT_MAX) {
		smbsr_error(sr, 0, ERRDOS, ERRbadaccess);
		return (SDRC_ERROR);
	}

	file_attr = op->dattr  & FILE_ATTRIBUTE_MASK;
	node = sr->fid_ofile->f_node;
	if (smb_node_getattr(sr, node, &attr) != 0) {
		smbsr_error(sr, NT_STATUS_INTERNAL_ERROR,
		    ERRDOS, ERROR_INTERNAL_ERROR);
		return (SDRC_ERROR);
	}

	rc = smbsr_encode_result(sr, 7, 0, "bwwllww",
	    7,
	    sr->smb_fid,
	    file_attr,
	    smb_time_gmt_to_local(sr, attr.sa_vattr.va_mtime.tv_sec),
	    (uint32_t)op->dsize,
	    op->omode,
	    (uint16_t)0);	/* bcc */

	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);
}
smb_sdrc_t
smb_com_open_andx(smb_request_t *sr)
{
	struct open_param	*op = &sr->arg.open;
	uint16_t		file_attr;
	smb_attr_t		attr;
	int rc;

	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 (op->create_disposition > FILE_MAXIMUM_DISPOSITION) {
		smbsr_error(sr, 0, ERRDOS, ERRbadaccess);
		return (SDRC_ERROR);
	}

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

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

	if (smb_open_dsize_check && op->dsize > UINT_MAX) {
		smbsr_error(sr, 0, ERRDOS, ERRbadaccess);
		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)) {

		smb_node_t *node = sr->fid_ofile->f_node;
		if (smb_node_getattr(sr, node, &attr) != 0) {
			smbsr_error(sr, NT_STATUS_INTERNAL_ERROR,
			    ERRDOS, ERROR_INTERNAL_ERROR);
			return (SDRC_ERROR);
		}

		rc = smbsr_encode_result(sr, 15, 0,
		    "bb.wwwllwwwwl2.w",
		    15,
		    sr->andx_com, VAR_BCC,
		    sr->smb_fid,
		    file_attr,
		    smb_time_gmt_to_local(sr, attr.sa_vattr.va_mtime.tv_sec),
		    (uint32_t)op->dsize,
		    op->omode, op->ftype,
		    op->devstate,
		    op->action_taken, op->fileid,
		    0);
	} else {
		rc = smbsr_encode_result(sr, 15, 0,
		    "bb.wwwllwwwwl2.w",
		    15,
		    sr->andx_com, VAR_BCC,
		    sr->smb_fid,
		    file_attr,
		    0L,
		    0L,
		    op->omode, op->ftype,
		    op->devstate,
		    op->action_taken, op->fileid,
		    0);
	}

	return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
}