smb_rename.c revision b1352070d318187b41b088da3533692976f3f225
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * CDDL HEADER START
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * The contents of this file are subject to the terms of the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Common Development and Distribution License (the "License").
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * You may not use this file except in compliance with the License.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * or http://www.opensolaris.org/os/licensing.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * See the License for the specific language governing permissions
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * and limitations under the License.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * When distributing Covered Code, include this CDDL HEADER in each
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * If applicable, add the following below this CDDL HEADER, with the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * fields enclosed by brackets "[]" replaced with your own identifying
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * information: Portions Copyright [yyyy] [name of copyright owner]
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * CDDL HEADER END
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Use is subject to license terms.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#include <smbsrv/nterror.h>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#include <sys/synch.h>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#include <smbsrv/smb_incl.h>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#include <smbsrv/smb_fsops.h>
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as#include <sys/nbmlock.h>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
b1352070d318187b41b088da3533692976f3f225Alan Wright/*
b1352070d318187b41b088da3533692976f3f225Alan Wright * NT_RENAME InformationLevels:
b1352070d318187b41b088da3533692976f3f225Alan Wright *
b1352070d318187b41b088da3533692976f3f225Alan Wright * SMB_NT_RENAME_MOVE_CLUSTER_INFO Server returns invalid parameter.
b1352070d318187b41b088da3533692976f3f225Alan Wright * SMB_NT_RENAME_SET_LINK_INFO Create a hard link to a file.
b1352070d318187b41b088da3533692976f3f225Alan Wright * SMB_NT_RENAME_RENAME_FILE In-place rename of a file.
b1352070d318187b41b088da3533692976f3f225Alan Wright * SMB_NT_RENAME_MOVE_FILE Move (rename) a file.
b1352070d318187b41b088da3533692976f3f225Alan Wright */
b1352070d318187b41b088da3533692976f3f225Alan Wright#define SMB_NT_RENAME_MOVE_CLUSTER_INFO 0x0102
b1352070d318187b41b088da3533692976f3f225Alan Wright#define SMB_NT_RENAME_SET_LINK_INFO 0x0103
b1352070d318187b41b088da3533692976f3f225Alan Wright#define SMB_NT_RENAME_RENAME_FILE 0x0104
b1352070d318187b41b088da3533692976f3f225Alan Wright#define SMB_NT_RENAME_MOVE_FILE 0x0105
b1352070d318187b41b088da3533692976f3f225Alan Wright
b89a8333f5e1f75ec0c269b22524bd2eccb972banatalie li - Sun Microsystems - Irvine United Statesstatic int smb_do_rename(smb_request_t *, smb_fqi_t *, smb_fqi_t *);
b1352070d318187b41b088da3533692976f3f225Alan Wrightstatic int smb_make_link(smb_request_t *, smb_fqi_t *, smb_fqi_t *);
b1352070d318187b41b088da3533692976f3f225Alan Wrightstatic int smb_rename_check_attr(smb_node_t *, uint16_t);
b1352070d318187b41b088da3533692976f3f225Alan Wrightstatic void smb_rename_set_error(smb_request_t *, int);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * smb_com_rename
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Rename a file. Files OldFileName must exist and NewFileName must not.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Both pathnames must be relative to the Tid specified in the request.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Open files may be renamed.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Multiple files may be renamed in response to a single request as Rename
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * File supports wildcards in the file name (last component of the path).
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * NOTE: we don't support rename with wildcards.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * SearchAttributes indicates the attributes that the target file(s) must
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * have. If SearchAttributes is zero then only normal files are renamed.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * If the system file or hidden attributes are specified then the rename
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * is inclusive - both the specified type(s) of files and normal files are
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * renamed. The encoding of SearchAttributes is described in section 3.10
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * - File Attribute Encoding.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
7b59d02d2a384be9a08087b14defadd214b3c1ddjbsmb_sdrc_t
faa1795a28a5c712eed6d0a3f84d98c368a316c6jbsmb_pre_rename(smb_request_t *sr)
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb{
b89a8333f5e1f75ec0c269b22524bd2eccb972banatalie li - Sun Microsystems - Irvine United States smb_fqi_t *src_fqi = &sr->arg.dirop.fqi;
b89a8333f5e1f75ec0c269b22524bd2eccb972banatalie li - Sun Microsystems - Irvine United States smb_fqi_t *dst_fqi = &sr->arg.dirop.dst_fqi;
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb int rc;
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb
eb1d736b1c19f6abeee90c921a9320b67fedd016afshin salek ardakani - Sun Microsystems - Irvine United States if ((rc = smbsr_decode_vwv(sr, "w", &src_fqi->fq_sattr)) == 0) {
eb1d736b1c19f6abeee90c921a9320b67fedd016afshin salek ardakani - Sun Microsystems - Irvine United States rc = smbsr_decode_data(sr, "%SS", sr, &src_fqi->fq_path.pn_path,
eb1d736b1c19f6abeee90c921a9320b67fedd016afshin salek ardakani - Sun Microsystems - Irvine United States &dst_fqi->fq_path.pn_path);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb
eb1d736b1c19f6abeee90c921a9320b67fedd016afshin salek ardakani - Sun Microsystems - Irvine United States dst_fqi->fq_sattr = 0;
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb }
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb DTRACE_SMB_2(op__Rename__start, smb_request_t *, sr,
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb struct dirop *, &sr->arg.dirop);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb}
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb
faa1795a28a5c712eed6d0a3f84d98c368a316c6jbvoid
faa1795a28a5c712eed6d0a3f84d98c368a316c6jbsmb_post_rename(smb_request_t *sr)
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb{
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb DTRACE_SMB_1(op__Rename__done, smb_request_t *, sr);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb}
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb
faa1795a28a5c712eed6d0a3f84d98c368a316c6jbsmb_sdrc_t
faa1795a28a5c712eed6d0a3f84d98c368a316c6jbsmb_com_rename(smb_request_t *sr)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
b89a8333f5e1f75ec0c269b22524bd2eccb972banatalie li - Sun Microsystems - Irvine United States smb_fqi_t *src_fqi = &sr->arg.dirop.fqi;
b89a8333f5e1f75ec0c269b22524bd2eccb972banatalie li - Sun Microsystems - Irvine United States smb_fqi_t *dst_fqi = &sr->arg.dirop.dst_fqi;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw int rc;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (!STYPE_ISDSK(sr->tid_tree->t_res_type)) {
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ERRDOS, ERROR_ACCESS_DENIED);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb return (SDRC_ERROR);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw rc = smb_do_rename(sr, src_fqi, dst_fqi);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (rc != 0) {
b1352070d318187b41b088da3533692976f3f225Alan Wright smb_rename_set_error(sr, rc);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb return (SDRC_ERROR);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
7b59d02d2a384be9a08087b14defadd214b3c1ddjb rc = smbsr_encode_empty_result(sr);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * smb_do_rename
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
b1352070d318187b41b088da3533692976f3f225Alan Wright * Common code for renaming a file.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
b1352070d318187b41b088da3533692976f3f225Alan Wright * If the source and destination are identical, we go through all
b1352070d318187b41b088da3533692976f3f225Alan Wright * the checks but we don't actually do the rename. If the source
b1352070d318187b41b088da3533692976f3f225Alan Wright * and destination files differ only in case, we do a case-sensitive
b1352070d318187b41b088da3533692976f3f225Alan Wright * rename. Otherwise, we do a full case-insensitive rename.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
b1352070d318187b41b088da3533692976f3f225Alan Wright * Returns errno values.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwstatic int
b1352070d318187b41b088da3533692976f3f225Alan Wrightsmb_do_rename(smb_request_t *sr, smb_fqi_t *src_fqi, smb_fqi_t *dst_fqi)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
b89a8333f5e1f75ec0c269b22524bd2eccb972banatalie li - Sun Microsystems - Irvine United States smb_node_t *src_node;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw char *dstname;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw DWORD status;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw int rc;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw int count;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
b1352070d318187b41b088da3533692976f3f225Alan Wright if ((rc = smbd_fs_query(sr, src_fqi, FQM_PATH_MUST_EXIST)) != 0)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (rc);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
eb1d736b1c19f6abeee90c921a9320b67fedd016afshin salek ardakani - Sun Microsystems - Irvine United States src_node = src_fqi->fq_fnode;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
b1352070d318187b41b088da3533692976f3f225Alan Wright if ((rc = smb_rename_check_attr(src_node, src_fqi->fq_sattr)) != 0)
b1352070d318187b41b088da3533692976f3f225Alan Wright goto rename_cleanup_nodes;
b1352070d318187b41b088da3533692976f3f225Alan Wright
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Break the oplock before access checks. If a client
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * has a file open, this will force a flush or close,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * which may affect the outcome of any share checking.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
fc724630b14603e4c1147df68b7bf45f7de7431fAlan Wright (void) smb_oplock_break(src_node, sr->session, B_FALSE);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as for (count = 0; count <= 3; count++) {
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as if (count) {
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as smb_node_end_crit(src_node);
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as delay(MSEC_TO_TICK(400));
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as smb_node_start_crit(src_node, RW_READER);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as status = smb_node_rename_check(src_node);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (status != NT_STATUS_SHARING_VIOLATION)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw break;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (status == NT_STATUS_SHARING_VIOLATION) {
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as smb_node_end_crit(src_node);
b1352070d318187b41b088da3533692976f3f225Alan Wright rc = EPIPE; /* = ERRbadshare */
b1352070d318187b41b088da3533692976f3f225Alan Wright goto rename_cleanup_nodes;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego status = smb_range_check(sr, src_node, 0, UINT64_MAX, B_TRUE);
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as if (status != NT_STATUS_SUCCESS) {
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as smb_node_end_crit(src_node);
b1352070d318187b41b088da3533692976f3f225Alan Wright rc = EACCES;
b1352070d318187b41b088da3533692976f3f225Alan Wright goto rename_cleanup_nodes;
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as }
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as
eb1d736b1c19f6abeee90c921a9320b67fedd016afshin salek ardakani - Sun Microsystems - Irvine United States if (utf8_strcasecmp(src_fqi->fq_path.pn_path,
eb1d736b1c19f6abeee90c921a9320b67fedd016afshin salek ardakani - Sun Microsystems - Irvine United States dst_fqi->fq_path.pn_path) == 0) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if ((rc = smbd_fs_query(sr, dst_fqi, 0)) != 0) {
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as smb_node_end_crit(src_node);
b1352070d318187b41b088da3533692976f3f225Alan Wright goto rename_cleanup_nodes;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Because the fqm parameter to smbd_fs_query() was 0,
b1352070d318187b41b088da3533692976f3f225Alan Wright * dst_fqi->fq_fnode may be NULL.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
eb1d736b1c19f6abeee90c921a9320b67fedd016afshin salek ardakani - Sun Microsystems - Irvine United States if (dst_fqi->fq_fnode)
eb1d736b1c19f6abeee90c921a9320b67fedd016afshin salek ardakani - Sun Microsystems - Irvine United States smb_node_release(dst_fqi->fq_fnode);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
eb1d736b1c19f6abeee90c921a9320b67fedd016afshin salek ardakani - Sun Microsystems - Irvine United States rc = strcmp(src_fqi->fq_od_name, dst_fqi->fq_last_comp);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (rc == 0) {
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as smb_node_end_crit(src_node);
b1352070d318187b41b088da3533692976f3f225Alan Wright goto rename_cleanup_nodes;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw rc = smb_fsop_rename(sr, sr->user_cr,
b1352070d318187b41b088da3533692976f3f225Alan Wright src_fqi->fq_dnode, src_fqi->fq_od_name,
b1352070d318187b41b088da3533692976f3f225Alan Wright dst_fqi->fq_dnode, dst_fqi->fq_last_comp);
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as smb_node_end_crit(src_node);
b1352070d318187b41b088da3533692976f3f225Alan Wright if (rc == 0)
b1352070d318187b41b088da3533692976f3f225Alan Wright smb_node_notify_change(dst_fqi->fq_dnode);
b1352070d318187b41b088da3533692976f3f225Alan Wright goto rename_cleanup_nodes;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw rc = smbd_fs_query(sr, dst_fqi, FQM_PATH_MUST_NOT_EXIST);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (rc != 0) {
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as smb_node_end_crit(src_node);
b1352070d318187b41b088da3533692976f3f225Alan Wright goto rename_cleanup_nodes;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /*
b1352070d318187b41b088da3533692976f3f225Alan Wright * On success of FQM_PATH_MUST_NOT_EXIST only dst_fqi->fq_dnode
b1352070d318187b41b088da3533692976f3f225Alan Wright * is valid (dst_fqi->fq_fnode is NULL).
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /*
b1352070d318187b41b088da3533692976f3f225Alan Wright * If the source name is mangled but the source and destination
b1352070d318187b41b088da3533692976f3f225Alan Wright * on-disk names are identical, we'll use the on-disk name.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
eb1d736b1c19f6abeee90c921a9320b67fedd016afshin salek ardakani - Sun Microsystems - Irvine United States if ((smb_maybe_mangled_name(src_fqi->fq_last_comp)) &&
eb1d736b1c19f6abeee90c921a9320b67fedd016afshin salek ardakani - Sun Microsystems - Irvine United States (strcmp(src_fqi->fq_last_comp, dst_fqi->fq_last_comp) == 0)) {
eb1d736b1c19f6abeee90c921a9320b67fedd016afshin salek ardakani - Sun Microsystems - Irvine United States dstname = src_fqi->fq_od_name;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw } else {
eb1d736b1c19f6abeee90c921a9320b67fedd016afshin salek ardakani - Sun Microsystems - Irvine United States dstname = dst_fqi->fq_last_comp;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw rc = smb_fsop_rename(sr, sr->user_cr,
b1352070d318187b41b088da3533692976f3f225Alan Wright src_fqi->fq_dnode, src_fqi->fq_od_name,
b1352070d318187b41b088da3533692976f3f225Alan Wright dst_fqi->fq_dnode, dstname);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
b1352070d318187b41b088da3533692976f3f225Alan Wright smb_node_end_crit(src_node);
b1352070d318187b41b088da3533692976f3f225Alan Wright
b1352070d318187b41b088da3533692976f3f225Alan Wright if (rc == 0)
b1352070d318187b41b088da3533692976f3f225Alan Wright smb_node_notify_change(dst_fqi->fq_dnode);
b1352070d318187b41b088da3533692976f3f225Alan Wright
b1352070d318187b41b088da3533692976f3f225Alan Wrightrename_cleanup_nodes:
b1352070d318187b41b088da3533692976f3f225Alan Wright smb_node_release(src_node);
b1352070d318187b41b088da3533692976f3f225Alan Wright smb_node_release(src_fqi->fq_dnode);
b1352070d318187b41b088da3533692976f3f225Alan Wright
b1352070d318187b41b088da3533692976f3f225Alan Wright if (dst_fqi->fq_dnode)
eb1d736b1c19f6abeee90c921a9320b67fedd016afshin salek ardakani - Sun Microsystems - Irvine United States smb_node_release(dst_fqi->fq_dnode);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
b1352070d318187b41b088da3533692976f3f225Alan Wright SMB_NULL_FQI_NODES(*src_fqi);
b1352070d318187b41b088da3533692976f3f225Alan Wright SMB_NULL_FQI_NODES(*dst_fqi);
b1352070d318187b41b088da3533692976f3f225Alan Wright return (rc);
b1352070d318187b41b088da3533692976f3f225Alan Wright}
b1352070d318187b41b088da3533692976f3f225Alan Wright
b1352070d318187b41b088da3533692976f3f225Alan Wright/*
b1352070d318187b41b088da3533692976f3f225Alan Wright * smb_com_nt_rename
b1352070d318187b41b088da3533692976f3f225Alan Wright *
b1352070d318187b41b088da3533692976f3f225Alan Wright * Rename a file. Files OldFileName must exist and NewFileName must not.
b1352070d318187b41b088da3533692976f3f225Alan Wright * Both pathnames must be relative to the Tid specified in the request.
b1352070d318187b41b088da3533692976f3f225Alan Wright * Open files may be renamed.
b1352070d318187b41b088da3533692976f3f225Alan Wright *
b1352070d318187b41b088da3533692976f3f225Alan Wright * Multiple files may be renamed in response to a single request as Rename
b1352070d318187b41b088da3533692976f3f225Alan Wright * File supports wildcards in the file name (last component of the path).
b1352070d318187b41b088da3533692976f3f225Alan Wright * NOTE: we don't support rename with wildcards.
b1352070d318187b41b088da3533692976f3f225Alan Wright *
b1352070d318187b41b088da3533692976f3f225Alan Wright * SearchAttributes indicates the attributes that the target file(s) must
b1352070d318187b41b088da3533692976f3f225Alan Wright * have. If SearchAttributes is zero then only normal files are renamed.
b1352070d318187b41b088da3533692976f3f225Alan Wright * If the system file or hidden attributes are specified then the rename
b1352070d318187b41b088da3533692976f3f225Alan Wright * is inclusive - both the specified type(s) of files and normal files are
b1352070d318187b41b088da3533692976f3f225Alan Wright * renamed. The encoding of SearchAttributes is described in section 3.10
b1352070d318187b41b088da3533692976f3f225Alan Wright * - File Attribute Encoding.
b1352070d318187b41b088da3533692976f3f225Alan Wright *
b1352070d318187b41b088da3533692976f3f225Alan Wright * Client Request Description
b1352070d318187b41b088da3533692976f3f225Alan Wright * ================================= ==================================
b1352070d318187b41b088da3533692976f3f225Alan Wright * UCHAR WordCount; Count of parameter words = 4
b1352070d318187b41b088da3533692976f3f225Alan Wright * USHORT SearchAttributes;
b1352070d318187b41b088da3533692976f3f225Alan Wright * USHORT InformationLevel; 0x0103 Create a hard link
b1352070d318187b41b088da3533692976f3f225Alan Wright * 0x0104 In-place rename
b1352070d318187b41b088da3533692976f3f225Alan Wright * 0x0105 Move (rename) a file
b1352070d318187b41b088da3533692976f3f225Alan Wright * ULONG ClusterCount Servers should ignore this value
b1352070d318187b41b088da3533692976f3f225Alan Wright * USHORT ByteCount; Count of data bytes; min = 4
b1352070d318187b41b088da3533692976f3f225Alan Wright * UCHAR Buffer[]; Buffer containing:
b1352070d318187b41b088da3533692976f3f225Alan Wright * UCHAR BufferFormat1 0x04
b1352070d318187b41b088da3533692976f3f225Alan Wright * UCHAR OldFileName[] OldFileName
b1352070d318187b41b088da3533692976f3f225Alan Wright * UCHAR BufferFormat1 0x04
b1352070d318187b41b088da3533692976f3f225Alan Wright * UCHAR OldFileName[] NewFileName
b1352070d318187b41b088da3533692976f3f225Alan Wright *
b1352070d318187b41b088da3533692976f3f225Alan Wright * Server Response Description
b1352070d318187b41b088da3533692976f3f225Alan Wright * ================================= ==================================
b1352070d318187b41b088da3533692976f3f225Alan Wright * UCHAR WordCount; Count of parameter words = 0
b1352070d318187b41b088da3533692976f3f225Alan Wright * UCHAR ByteCount; Count of data bytes = 0
b1352070d318187b41b088da3533692976f3f225Alan Wright */
b1352070d318187b41b088da3533692976f3f225Alan Wrightsmb_sdrc_t
b1352070d318187b41b088da3533692976f3f225Alan Wrightsmb_pre_nt_rename(smb_request_t *sr)
b1352070d318187b41b088da3533692976f3f225Alan Wright{
b1352070d318187b41b088da3533692976f3f225Alan Wright smb_fqi_t *src_fqi = &sr->arg.dirop.fqi;
b1352070d318187b41b088da3533692976f3f225Alan Wright smb_fqi_t *dst_fqi = &sr->arg.dirop.dst_fqi;
b1352070d318187b41b088da3533692976f3f225Alan Wright uint32_t clusters;
b1352070d318187b41b088da3533692976f3f225Alan Wright int rc;
b1352070d318187b41b088da3533692976f3f225Alan Wright
b1352070d318187b41b088da3533692976f3f225Alan Wright rc = smbsr_decode_vwv(sr, "wwl", &src_fqi->fq_sattr,
b1352070d318187b41b088da3533692976f3f225Alan Wright &sr->arg.dirop.info_level, &clusters);
b1352070d318187b41b088da3533692976f3f225Alan Wright if (rc == 0) {
b1352070d318187b41b088da3533692976f3f225Alan Wright rc = smbsr_decode_data(sr, "%SS", sr,
b1352070d318187b41b088da3533692976f3f225Alan Wright &src_fqi->fq_path.pn_path, &dst_fqi->fq_path.pn_path);
b1352070d318187b41b088da3533692976f3f225Alan Wright
b1352070d318187b41b088da3533692976f3f225Alan Wright dst_fqi->fq_sattr = 0;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
b1352070d318187b41b088da3533692976f3f225Alan Wright DTRACE_SMB_2(op__NtRename__start, smb_request_t *, sr,
b1352070d318187b41b088da3533692976f3f225Alan Wright struct dirop *, &sr->arg.dirop);
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as
b1352070d318187b41b088da3533692976f3f225Alan Wright return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
b1352070d318187b41b088da3533692976f3f225Alan Wright}
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as
b1352070d318187b41b088da3533692976f3f225Alan Wrightvoid
b1352070d318187b41b088da3533692976f3f225Alan Wrightsmb_post_nt_rename(smb_request_t *sr)
b1352070d318187b41b088da3533692976f3f225Alan Wright{
b1352070d318187b41b088da3533692976f3f225Alan Wright DTRACE_SMB_1(op__NtRename__done, smb_request_t *, sr);
b1352070d318187b41b088da3533692976f3f225Alan Wright}
b1352070d318187b41b088da3533692976f3f225Alan Wright
b1352070d318187b41b088da3533692976f3f225Alan Wrightsmb_sdrc_t
b1352070d318187b41b088da3533692976f3f225Alan Wrightsmb_com_nt_rename(smb_request_t *sr)
b1352070d318187b41b088da3533692976f3f225Alan Wright{
b1352070d318187b41b088da3533692976f3f225Alan Wright smb_fqi_t *src_fqi = &sr->arg.dirop.fqi;
b1352070d318187b41b088da3533692976f3f225Alan Wright smb_fqi_t *dst_fqi = &sr->arg.dirop.dst_fqi;
b1352070d318187b41b088da3533692976f3f225Alan Wright int rc;
b1352070d318187b41b088da3533692976f3f225Alan Wright
b1352070d318187b41b088da3533692976f3f225Alan Wright if (!STYPE_ISDSK(sr->tid_tree->t_res_type)) {
b1352070d318187b41b088da3533692976f3f225Alan Wright smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
b1352070d318187b41b088da3533692976f3f225Alan Wright ERRDOS, ERROR_ACCESS_DENIED);
b1352070d318187b41b088da3533692976f3f225Alan Wright return (SDRC_ERROR);
b1352070d318187b41b088da3533692976f3f225Alan Wright }
b1352070d318187b41b088da3533692976f3f225Alan Wright
b1352070d318187b41b088da3533692976f3f225Alan Wright if (smb_convert_wildcards(src_fqi->fq_path.pn_path) != 0) {
b1352070d318187b41b088da3533692976f3f225Alan Wright smbsr_error(sr, NT_STATUS_OBJECT_PATH_SYNTAX_BAD,
b1352070d318187b41b088da3533692976f3f225Alan Wright ERRDOS, ERROR_BAD_PATHNAME);
b1352070d318187b41b088da3533692976f3f225Alan Wright return (SDRC_ERROR);
b1352070d318187b41b088da3533692976f3f225Alan Wright }
b1352070d318187b41b088da3533692976f3f225Alan Wright
b1352070d318187b41b088da3533692976f3f225Alan Wright switch (sr->arg.dirop.info_level) {
b1352070d318187b41b088da3533692976f3f225Alan Wright case SMB_NT_RENAME_SET_LINK_INFO:
b1352070d318187b41b088da3533692976f3f225Alan Wright rc = smb_make_link(sr, src_fqi, dst_fqi);
b1352070d318187b41b088da3533692976f3f225Alan Wright break;
b1352070d318187b41b088da3533692976f3f225Alan Wright case SMB_NT_RENAME_RENAME_FILE:
b1352070d318187b41b088da3533692976f3f225Alan Wright case SMB_NT_RENAME_MOVE_FILE:
b1352070d318187b41b088da3533692976f3f225Alan Wright rc = smb_do_rename(sr, src_fqi, dst_fqi);
b1352070d318187b41b088da3533692976f3f225Alan Wright break;
b1352070d318187b41b088da3533692976f3f225Alan Wright case SMB_NT_RENAME_MOVE_CLUSTER_INFO:
b1352070d318187b41b088da3533692976f3f225Alan Wright rc = EINVAL;
b1352070d318187b41b088da3533692976f3f225Alan Wright break;
b1352070d318187b41b088da3533692976f3f225Alan Wright default:
b1352070d318187b41b088da3533692976f3f225Alan Wright rc = EACCES;
b1352070d318187b41b088da3533692976f3f225Alan Wright break;
b1352070d318187b41b088da3533692976f3f225Alan Wright }
b1352070d318187b41b088da3533692976f3f225Alan Wright
b1352070d318187b41b088da3533692976f3f225Alan Wright if (rc != 0) {
b1352070d318187b41b088da3533692976f3f225Alan Wright smb_rename_set_error(sr, rc);
b1352070d318187b41b088da3533692976f3f225Alan Wright return (SDRC_ERROR);
b1352070d318187b41b088da3533692976f3f225Alan Wright }
b1352070d318187b41b088da3533692976f3f225Alan Wright
b1352070d318187b41b088da3533692976f3f225Alan Wright rc = smbsr_encode_empty_result(sr);
b1352070d318187b41b088da3533692976f3f225Alan Wright return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
b1352070d318187b41b088da3533692976f3f225Alan Wright}
b1352070d318187b41b088da3533692976f3f225Alan Wright
b1352070d318187b41b088da3533692976f3f225Alan Wright/*
b1352070d318187b41b088da3533692976f3f225Alan Wright * smb_make_link
b1352070d318187b41b088da3533692976f3f225Alan Wright *
b1352070d318187b41b088da3533692976f3f225Alan Wright * Common code for creating a hard link (adding an additional name
b1352070d318187b41b088da3533692976f3f225Alan Wright * for a file.
b1352070d318187b41b088da3533692976f3f225Alan Wright *
b1352070d318187b41b088da3533692976f3f225Alan Wright * If the source and destination are identical, we go through all
b1352070d318187b41b088da3533692976f3f225Alan Wright * the checks but we don't create a link.
b1352070d318187b41b088da3533692976f3f225Alan Wright *
b1352070d318187b41b088da3533692976f3f225Alan Wright * Returns errno values.
b1352070d318187b41b088da3533692976f3f225Alan Wright */
b1352070d318187b41b088da3533692976f3f225Alan Wrightstatic int
b1352070d318187b41b088da3533692976f3f225Alan Wrightsmb_make_link(smb_request_t *sr, smb_fqi_t *src_fqi, smb_fqi_t *dst_fqi)
b1352070d318187b41b088da3533692976f3f225Alan Wright{
b1352070d318187b41b088da3533692976f3f225Alan Wright smb_node_t *src_fnode;
b1352070d318187b41b088da3533692976f3f225Alan Wright DWORD status;
b1352070d318187b41b088da3533692976f3f225Alan Wright int rc;
b1352070d318187b41b088da3533692976f3f225Alan Wright int count;
b1352070d318187b41b088da3533692976f3f225Alan Wright
b1352070d318187b41b088da3533692976f3f225Alan Wright if ((rc = smbd_fs_query(sr, src_fqi, FQM_PATH_MUST_EXIST)) != 0)
b1352070d318187b41b088da3533692976f3f225Alan Wright return (rc);
b1352070d318187b41b088da3533692976f3f225Alan Wright
b1352070d318187b41b088da3533692976f3f225Alan Wright src_fnode = src_fqi->fq_fnode;
b1352070d318187b41b088da3533692976f3f225Alan Wright
b1352070d318187b41b088da3533692976f3f225Alan Wright if ((rc = smb_rename_check_attr(src_fnode, src_fqi->fq_sattr)) != 0)
b1352070d318187b41b088da3533692976f3f225Alan Wright goto link_cleanup_nodes;
b1352070d318187b41b088da3533692976f3f225Alan Wright
b1352070d318187b41b088da3533692976f3f225Alan Wright /*
b1352070d318187b41b088da3533692976f3f225Alan Wright * Break the oplock before access checks. If a client
b1352070d318187b41b088da3533692976f3f225Alan Wright * has a file open, this will force a flush or close,
b1352070d318187b41b088da3533692976f3f225Alan Wright * which may affect the outcome of any share checking.
b1352070d318187b41b088da3533692976f3f225Alan Wright */
b1352070d318187b41b088da3533692976f3f225Alan Wright (void) smb_oplock_break(src_fnode, sr->session, B_FALSE);
b1352070d318187b41b088da3533692976f3f225Alan Wright
b1352070d318187b41b088da3533692976f3f225Alan Wright for (count = 0; count <= 3; count++) {
b1352070d318187b41b088da3533692976f3f225Alan Wright if (count) {
b1352070d318187b41b088da3533692976f3f225Alan Wright smb_node_end_crit(src_fnode);
b1352070d318187b41b088da3533692976f3f225Alan Wright delay(MSEC_TO_TICK(400));
b1352070d318187b41b088da3533692976f3f225Alan Wright }
b1352070d318187b41b088da3533692976f3f225Alan Wright
b1352070d318187b41b088da3533692976f3f225Alan Wright smb_node_start_crit(src_fnode, RW_READER);
b1352070d318187b41b088da3533692976f3f225Alan Wright status = smb_node_rename_check(src_fnode);
b1352070d318187b41b088da3533692976f3f225Alan Wright
b1352070d318187b41b088da3533692976f3f225Alan Wright if (status != NT_STATUS_SHARING_VIOLATION)
b1352070d318187b41b088da3533692976f3f225Alan Wright break;
b1352070d318187b41b088da3533692976f3f225Alan Wright }
b1352070d318187b41b088da3533692976f3f225Alan Wright
b1352070d318187b41b088da3533692976f3f225Alan Wright if (status == NT_STATUS_SHARING_VIOLATION) {
b1352070d318187b41b088da3533692976f3f225Alan Wright smb_node_end_crit(src_fnode);
b1352070d318187b41b088da3533692976f3f225Alan Wright rc = EPIPE; /* = ERRbadshare */
b1352070d318187b41b088da3533692976f3f225Alan Wright goto link_cleanup_nodes;
b1352070d318187b41b088da3533692976f3f225Alan Wright }
b1352070d318187b41b088da3533692976f3f225Alan Wright
b1352070d318187b41b088da3533692976f3f225Alan Wright status = smb_range_check(sr, src_fnode, 0, UINT64_MAX, B_TRUE);
b1352070d318187b41b088da3533692976f3f225Alan Wright
b1352070d318187b41b088da3533692976f3f225Alan Wright if (status != NT_STATUS_SUCCESS) {
b1352070d318187b41b088da3533692976f3f225Alan Wright smb_node_end_crit(src_fnode);
b1352070d318187b41b088da3533692976f3f225Alan Wright rc = EACCES;
b1352070d318187b41b088da3533692976f3f225Alan Wright goto link_cleanup_nodes;
b1352070d318187b41b088da3533692976f3f225Alan Wright }
b1352070d318187b41b088da3533692976f3f225Alan Wright
b1352070d318187b41b088da3533692976f3f225Alan Wright if (utf8_strcasecmp(src_fqi->fq_path.pn_path,
b1352070d318187b41b088da3533692976f3f225Alan Wright dst_fqi->fq_path.pn_path) == 0) {
b1352070d318187b41b088da3533692976f3f225Alan Wright smb_node_end_crit(src_fnode);
b1352070d318187b41b088da3533692976f3f225Alan Wright rc = 0;
b1352070d318187b41b088da3533692976f3f225Alan Wright goto link_cleanup_nodes;
b1352070d318187b41b088da3533692976f3f225Alan Wright }
b1352070d318187b41b088da3533692976f3f225Alan Wright
b1352070d318187b41b088da3533692976f3f225Alan Wright rc = smbd_fs_query(sr, dst_fqi, FQM_PATH_MUST_NOT_EXIST);
b1352070d318187b41b088da3533692976f3f225Alan Wright if (rc != 0) {
b1352070d318187b41b088da3533692976f3f225Alan Wright smb_node_end_crit(src_fnode);
b1352070d318187b41b088da3533692976f3f225Alan Wright goto link_cleanup_nodes;
b1352070d318187b41b088da3533692976f3f225Alan Wright }
b1352070d318187b41b088da3533692976f3f225Alan Wright
b1352070d318187b41b088da3533692976f3f225Alan Wright /*
b1352070d318187b41b088da3533692976f3f225Alan Wright * On success of FQM_PATH_MUST_NOT_EXIST only dst_fqi->fq_dnode
b1352070d318187b41b088da3533692976f3f225Alan Wright * is valid (dst_fqi->fq_fnode is NULL).
b1352070d318187b41b088da3533692976f3f225Alan Wright */
b1352070d318187b41b088da3533692976f3f225Alan Wright rc = smb_fsop_link(sr, sr->user_cr, dst_fqi->fq_dnode, src_fnode,
b1352070d318187b41b088da3533692976f3f225Alan Wright dst_fqi->fq_last_comp);
b1352070d318187b41b088da3533692976f3f225Alan Wright
b1352070d318187b41b088da3533692976f3f225Alan Wright smb_node_end_crit(src_fnode);
b1352070d318187b41b088da3533692976f3f225Alan Wright
b1352070d318187b41b088da3533692976f3f225Alan Wright if (rc == 0)
b1352070d318187b41b088da3533692976f3f225Alan Wright smb_node_notify_change(dst_fqi->fq_dnode);
b1352070d318187b41b088da3533692976f3f225Alan Wright
b1352070d318187b41b088da3533692976f3f225Alan Wrightlink_cleanup_nodes:
b1352070d318187b41b088da3533692976f3f225Alan Wright smb_node_release(src_fnode);
b1352070d318187b41b088da3533692976f3f225Alan Wright smb_node_release(src_fqi->fq_dnode);
b1352070d318187b41b088da3533692976f3f225Alan Wright
b1352070d318187b41b088da3533692976f3f225Alan Wright if (dst_fqi->fq_dnode)
b1352070d318187b41b088da3533692976f3f225Alan Wright smb_node_release(dst_fqi->fq_dnode);
b1352070d318187b41b088da3533692976f3f225Alan Wright
b1352070d318187b41b088da3533692976f3f225Alan Wright SMB_NULL_FQI_NODES(*src_fqi);
b1352070d318187b41b088da3533692976f3f225Alan Wright SMB_NULL_FQI_NODES(*dst_fqi);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (rc);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
b1352070d318187b41b088da3533692976f3f225Alan Wright
b1352070d318187b41b088da3533692976f3f225Alan Wrightstatic int
b1352070d318187b41b088da3533692976f3f225Alan Wrightsmb_rename_check_attr(smb_node_t *node, uint16_t sattr)
b1352070d318187b41b088da3533692976f3f225Alan Wright{
b1352070d318187b41b088da3533692976f3f225Alan Wright uint16_t dosattr = smb_node_get_dosattr(node);
b1352070d318187b41b088da3533692976f3f225Alan Wright
b1352070d318187b41b088da3533692976f3f225Alan Wright if ((dosattr & FILE_ATTRIBUTE_HIDDEN) && !(SMB_SEARCH_HIDDEN(sattr)))
b1352070d318187b41b088da3533692976f3f225Alan Wright return (ESRCH);
b1352070d318187b41b088da3533692976f3f225Alan Wright
b1352070d318187b41b088da3533692976f3f225Alan Wright if ((dosattr & FILE_ATTRIBUTE_SYSTEM) && !(SMB_SEARCH_SYSTEM(sattr)))
b1352070d318187b41b088da3533692976f3f225Alan Wright return (ESRCH);
b1352070d318187b41b088da3533692976f3f225Alan Wright
b1352070d318187b41b088da3533692976f3f225Alan Wright return (0);
b1352070d318187b41b088da3533692976f3f225Alan Wright}
b1352070d318187b41b088da3533692976f3f225Alan Wright
b1352070d318187b41b088da3533692976f3f225Alan Wright/*
b1352070d318187b41b088da3533692976f3f225Alan Wright * The following values are based on observed WFWG, Windows 9x, Windows NT
b1352070d318187b41b088da3533692976f3f225Alan Wright * and Windows 2000 behaviour.
b1352070d318187b41b088da3533692976f3f225Alan Wright *
b1352070d318187b41b088da3533692976f3f225Alan Wright * ERROR_FILE_EXISTS doesn't work for Windows 98 clients.
b1352070d318187b41b088da3533692976f3f225Alan Wright *
b1352070d318187b41b088da3533692976f3f225Alan Wright * Windows 95 clients don't see the problem because the target is deleted
b1352070d318187b41b088da3533692976f3f225Alan Wright * before the rename request.
b1352070d318187b41b088da3533692976f3f225Alan Wright */
b1352070d318187b41b088da3533692976f3f225Alan Wrightstatic void
b1352070d318187b41b088da3533692976f3f225Alan Wrightsmb_rename_set_error(smb_request_t *sr, int errnum)
b1352070d318187b41b088da3533692976f3f225Alan Wright{
b1352070d318187b41b088da3533692976f3f225Alan Wright static struct {
b1352070d318187b41b088da3533692976f3f225Alan Wright int errnum;
b1352070d318187b41b088da3533692976f3f225Alan Wright uint16_t errcode;
b1352070d318187b41b088da3533692976f3f225Alan Wright uint32_t status32;
b1352070d318187b41b088da3533692976f3f225Alan Wright } rc_map[] = {
b1352070d318187b41b088da3533692976f3f225Alan Wright { EEXIST, ERROR_ALREADY_EXISTS, NT_STATUS_OBJECT_NAME_COLLISION },
b1352070d318187b41b088da3533692976f3f225Alan Wright { EPIPE, ERROR_SHARING_VIOLATION, NT_STATUS_SHARING_VIOLATION },
b1352070d318187b41b088da3533692976f3f225Alan Wright { ENOENT, ERROR_FILE_NOT_FOUND, NT_STATUS_OBJECT_NAME_NOT_FOUND },
b1352070d318187b41b088da3533692976f3f225Alan Wright { ESRCH, ERROR_FILE_NOT_FOUND, NT_STATUS_NO_SUCH_FILE },
b1352070d318187b41b088da3533692976f3f225Alan Wright { EINVAL, ERROR_INVALID_PARAMETER, NT_STATUS_INVALID_PARAMETER },
b1352070d318187b41b088da3533692976f3f225Alan Wright { EACCES, ERROR_ACCESS_DENIED, NT_STATUS_ACCESS_DENIED }
b1352070d318187b41b088da3533692976f3f225Alan Wright };
b1352070d318187b41b088da3533692976f3f225Alan Wright
b1352070d318187b41b088da3533692976f3f225Alan Wright int i;
b1352070d318187b41b088da3533692976f3f225Alan Wright
b1352070d318187b41b088da3533692976f3f225Alan Wright if (errnum == 0)
b1352070d318187b41b088da3533692976f3f225Alan Wright return;
b1352070d318187b41b088da3533692976f3f225Alan Wright
b1352070d318187b41b088da3533692976f3f225Alan Wright for (i = 0; i < sizeof (rc_map)/sizeof (rc_map[0]); ++i) {
b1352070d318187b41b088da3533692976f3f225Alan Wright if (rc_map[i].errnum == errnum) {
b1352070d318187b41b088da3533692976f3f225Alan Wright smbsr_error(sr, rc_map[i].status32,
b1352070d318187b41b088da3533692976f3f225Alan Wright ERRDOS, rc_map[i].errcode);
b1352070d318187b41b088da3533692976f3f225Alan Wright return;
b1352070d318187b41b088da3533692976f3f225Alan Wright }
b1352070d318187b41b088da3533692976f3f225Alan Wright }
b1352070d318187b41b088da3533692976f3f225Alan Wright
b1352070d318187b41b088da3533692976f3f225Alan Wright smbsr_errno(sr, errnum);
b1352070d318187b41b088da3533692976f3f225Alan Wright}