smb_rename.c revision 5fd03bc0f2e00e7ba02316c2e08f45d52aab15db
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/*
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#include <sys/synch.h>
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown#include <smbsrv/smb_kproto.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
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown/*
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown * SMB_TRANS2_SET_FILE/PATH_INFO (RENAME_INFORMATION level) flag
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown */
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown#define SMB_RENAME_FLAG_OVERWRITE 0x001
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brownstatic int smb_common_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 *);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brownstatic int smb_rename_check_stream(smb_fqi_t *, smb_fqi_t *);
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintoshstatic int smb_rename_check_attr(smb_request_t *, smb_node_t *, uint16_t);
b1352070d318187b41b088da3533692976f3f225Alan Wrightstatic void smb_rename_set_error(smb_request_t *, int);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brownstatic int smb_rename_lookup_src(smb_request_t *);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brownstatic void smb_rename_release_src(smb_request_t *);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown
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
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown * renamed.
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{
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States int rc;
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States smb_fqi_t *src_fqi = &sr->arg.dirop.fqi;
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States smb_fqi_t *dst_fqi = &sr->arg.dirop.dst_fqi;
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States smb_pathname_t *src_pn = &src_fqi->fq_path;
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States smb_pathname_t *dst_pn = &dst_fqi->fq_path;
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
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States smb_pathname_init(sr, src_pn, src_pn->pn_path);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States smb_pathname_init(sr, dst_pn, dst_pn->pn_path);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States if (!smb_pathname_validate(sr, src_pn) ||
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States !smb_pathname_validate(sr, dst_pn)) {
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States return (SDRC_ERROR);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States }
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown rc = smb_common_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
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 * 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
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown * renamed.
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{
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States int rc;
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States smb_fqi_t *src_fqi = &sr->arg.dirop.fqi;
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States smb_fqi_t *dst_fqi = &sr->arg.dirop.dst_fqi;
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States smb_pathname_t *src_pn = &src_fqi->fq_path;
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States smb_pathname_t *dst_pn = &dst_fqi->fq_path;
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
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States smb_pathname_init(sr, src_pn, src_pn->pn_path);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States smb_pathname_init(sr, dst_pn, dst_pn->pn_path);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States if (!smb_pathname_validate(sr, src_pn) ||
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States !smb_pathname_validate(sr, dst_pn)) {
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States return (SDRC_ERROR);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States }
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States if (smb_contains_wildcards(src_pn->pn_path)) {
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:
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown rc = smb_common_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
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown/*
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown * smb_nt_transact_rename
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown *
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown * Windows servers return SUCCESS without renaming file.
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown * The only check required is to check that the handle (fid) is valid.
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown */
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brownsmb_sdrc_t
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brownsmb_nt_transact_rename(smb_request_t *sr, smb_xa_t *xa)
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown{
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown if (smb_mbc_decodef(&xa->req_param_mb, "w", &sr->smb_fid) != 0)
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown return (SDRC_ERROR);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown smbsr_lookup_file(sr);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown if (sr->fid_ofile == NULL) {
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown return (SDRC_ERROR);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown }
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown smbsr_release_file(sr);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown return (SDRC_SUCCESS);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown}
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown/*
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown * smb_trans2_rename
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown *
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown * Implements SMB_FILE_RENAME_INFORMATION level of Trans2_Set_FileInfo
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown * and Trans2_Set_PathInfo.
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown * If the new filename (dst_fqi) already exists it may be overwritten
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown * if flags == 1.
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown */
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brownint
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brownsmb_trans2_rename(smb_request_t *sr, smb_node_t *node, char *fname, int flags)
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown{
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States int rc = 0;
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States smb_fqi_t *src_fqi = &sr->arg.dirop.fqi;
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States smb_fqi_t *dst_fqi = &sr->arg.dirop.dst_fqi;
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States smb_pathname_t *dst_pn = &dst_fqi->fq_path;
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States char *path;
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States int len;
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown sr->arg.dirop.flags = flags ? SMB_RENAME_FLAG_OVERWRITE : 0;
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown sr->arg.dirop.info_level = SMB_NT_RENAME_RENAME_FILE;
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown src_fqi->fq_sattr = SMB_SEARCH_ATTRIBUTES;
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown src_fqi->fq_fnode = node;
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown src_fqi->fq_dnode = node->n_dnode;
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States /* costruct and validate the dst pathname */
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States path = smb_srm_zalloc(sr, MAXPATHLEN);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States if (src_fqi->fq_path.pn_pname) {
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States (void) snprintf(path, MAXPATHLEN, "%s\\%s",
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States src_fqi->fq_path.pn_pname, fname);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States } else {
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States rc = smb_node_getshrpath(node->n_dnode, sr->tid_tree,
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States path, MAXPATHLEN);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States if (rc != 0) {
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States smb_rename_set_error(sr, rc);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States return (-1);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States }
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States len = strlen(path);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States (void) snprintf(path + len, MAXPATHLEN - len, "\\%s", fname);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States }
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States smb_pathname_init(sr, dst_pn, path);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States if (!smb_pathname_validate(sr, dst_pn))
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States return (-1);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown dst_fqi->fq_dnode = node->n_dnode;
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States (void) strlcpy(dst_fqi->fq_last_comp, dst_pn->pn_fname, MAXNAMELEN);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown rc = smb_common_rename(sr, src_fqi, dst_fqi);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown if (rc != 0) {
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown smb_rename_set_error(sr, rc);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown return (-1);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown }
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown return (0);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown}
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown/*
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown * smb_common_rename
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown *
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown * Common code for renaming a file.
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown *
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown * If the source and destination are identical, we go through all
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown * the checks but we don't actually do the rename. If the source
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown * and destination files differ only in case, we do a case-sensitive
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown * rename. Otherwise, we do a full case-insensitive rename.
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown *
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown * Returns errno values.
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown */
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brownstatic int
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brownsmb_common_rename(smb_request_t *sr, smb_fqi_t *src_fqi, smb_fqi_t *dst_fqi)
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown{
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown smb_node_t *src_fnode, *src_dnode, *dst_fnode, *dst_dnode;
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown smb_node_t *tnode;
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown int rc, count;
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown DWORD status;
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown char *new_name, *path;
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown path = dst_fqi->fq_path.pn_path;
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown /* Check if attempting to rename a stream - not yet supported */
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown rc = smb_rename_check_stream(src_fqi, dst_fqi);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown if (rc != 0)
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown return (rc);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown /* The source node may already have been provided */
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown if (src_fqi->fq_fnode) {
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown smb_node_start_crit(src_fqi->fq_fnode, RW_READER);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown smb_node_ref(src_fqi->fq_fnode);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown smb_node_ref(src_fqi->fq_dnode);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown } else {
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown /* lookup and validate src node */
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown rc = smb_rename_lookup_src(sr);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown if (rc != 0)
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown return (rc);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown }
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown src_fnode = src_fqi->fq_fnode;
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown src_dnode = src_fqi->fq_dnode;
896cab575ec8a9c845350d470dabb5a0997efebfDan McDonald tnode = sr->tid_tree->t_snode;
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown /* Find destination dnode and last_comp */
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown if (dst_fqi->fq_dnode) {
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown smb_node_ref(dst_fqi->fq_dnode);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown } else {
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown rc = smb_pathname_reduce(sr, sr->user_cr, path, tnode, tnode,
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown &dst_fqi->fq_dnode, dst_fqi->fq_last_comp);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown if (rc != 0) {
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown smb_rename_release_src(sr);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown return (rc);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown }
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown }
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown dst_dnode = dst_fqi->fq_dnode;
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown new_name = dst_fqi->fq_last_comp;
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown /* If exact name match in same directory, we're done */
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown if ((src_dnode == dst_dnode) &&
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown (strcmp(src_fnode->od_name, new_name) == 0)) {
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown smb_rename_release_src(sr);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown smb_node_release(dst_dnode);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown return (0);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown }
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown /* Lookup destination node */
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown rc = smb_fsop_lookup(sr, sr->user_cr, 0, tnode,
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown dst_dnode, new_name, &dst_fqi->fq_fnode);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier /* If the destination node doesn't already exist, validate new_name. */
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier if (rc == ENOENT) {
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier if (smb_is_invalid_filename(new_name)) {
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier smb_rename_release_src(sr);
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier smb_node_release(dst_dnode);
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier return (EILSEQ); /* NT_STATUS_OBJECT_NAME_INVALID */
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier }
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier }
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown /*
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown * Handle case where changing case of the same directory entry.
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown *
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown * If we found the dst node in the same directory as the src node,
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown * and their names differ only in case:
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown *
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown * If the tree is case sensitive (or mixed):
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown * Do case sensitive lookup to see if exact match exists.
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown * If the exact match is the same node as src_node we're done.
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown *
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown * If the tree is case insensitive:
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown * There is currently no way to tell if the case is different
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown * or not, so do the rename (unless the specified new name was
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown * mangled).
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown */
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown if ((rc == 0) &&
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown (src_dnode == dst_dnode) &&
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown (smb_strcasecmp(src_fnode->od_name,
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown dst_fqi->fq_fnode->od_name, 0) == 0)) {
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown smb_node_release(dst_fqi->fq_fnode);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown dst_fqi->fq_fnode = NULL;
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown if (smb_tree_has_feature(sr->tid_tree,
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown SMB_TREE_NO_CASESENSITIVE)) {
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown if (smb_strcasecmp(src_fnode->od_name,
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown dst_fqi->fq_last_comp, 0) != 0) {
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown smb_rename_release_src(sr);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown smb_node_release(dst_dnode);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown return (0);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown }
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown } else {
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown rc = smb_fsop_lookup(sr, sr->user_cr,
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown SMB_CASE_SENSITIVE, tnode, dst_dnode, new_name,
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown &dst_fqi->fq_fnode);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown if ((rc == 0) &&
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown (dst_fqi->fq_fnode == src_fnode)) {
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown smb_rename_release_src(sr);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown smb_node_release(dst_fqi->fq_fnode);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown smb_node_release(dst_dnode);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown return (0);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown }
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown }
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown }
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown if ((rc != 0) && (rc != ENOENT)) {
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown smb_rename_release_src(sr);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown smb_node_release(dst_fqi->fq_dnode);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown return (rc);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown }
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown if (dst_fqi->fq_fnode) {
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown dst_fnode = dst_fqi->fq_fnode;
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown if (!(sr->arg.dirop.flags && SMB_RENAME_FLAG_OVERWRITE)) {
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown smb_rename_release_src(sr);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown smb_node_release(dst_fnode);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown smb_node_release(dst_dnode);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown return (EEXIST);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown }
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh (void) smb_oplock_break(sr, dst_fnode,
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh SMB_OPLOCK_BREAK_TO_NONE | SMB_OPLOCK_BREAK_BATCH);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown for (count = 0; count <= 3; count++) {
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown if (count) {
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown smb_node_end_crit(dst_fnode);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown delay(MSEC_TO_TICK(400));
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown }
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown smb_node_start_crit(dst_fnode, RW_READER);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown status = smb_node_delete_check(dst_fnode);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown if (status != NT_STATUS_SHARING_VIOLATION)
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown break;
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown }
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown if (status != NT_STATUS_SHARING_VIOLATION)
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown status = smb_range_check(sr, dst_fnode,
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown 0, UINT64_MAX, B_TRUE);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown if (status != NT_STATUS_SUCCESS) {
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown smb_rename_release_src(sr);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown smb_node_end_crit(dst_fnode);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown smb_node_release(dst_fnode);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown smb_node_release(dst_dnode);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown return (EACCES);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown }
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier new_name = dst_fnode->od_name;
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown }
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown rc = smb_fsop_rename(sr, sr->user_cr,
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown src_dnode, src_fnode->od_name,
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown dst_dnode, new_name);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown
ccc71be50bb49efb4e31004c77fb3e065e9c0596Gordon Ross if (rc == 0) {
ccc71be50bb49efb4e31004c77fb3e065e9c0596Gordon Ross /*
ccc71be50bb49efb4e31004c77fb3e065e9c0596Gordon Ross * Note that renames in the same directory are normally
ccc71be50bb49efb4e31004c77fb3e065e9c0596Gordon Ross * delivered in {old,new} pairs, and clients expect them
ccc71be50bb49efb4e31004c77fb3e065e9c0596Gordon Ross * in that order, if both events are delivered.
ccc71be50bb49efb4e31004c77fb3e065e9c0596Gordon Ross */
ccc71be50bb49efb4e31004c77fb3e065e9c0596Gordon Ross int a_src, a_dst; /* action codes */
ccc71be50bb49efb4e31004c77fb3e065e9c0596Gordon Ross if (src_dnode == dst_dnode) {
ccc71be50bb49efb4e31004c77fb3e065e9c0596Gordon Ross a_src = FILE_ACTION_RENAMED_OLD_NAME;
ccc71be50bb49efb4e31004c77fb3e065e9c0596Gordon Ross a_dst = FILE_ACTION_RENAMED_NEW_NAME;
ccc71be50bb49efb4e31004c77fb3e065e9c0596Gordon Ross } else {
ccc71be50bb49efb4e31004c77fb3e065e9c0596Gordon Ross a_src = FILE_ACTION_REMOVED;
ccc71be50bb49efb4e31004c77fb3e065e9c0596Gordon Ross a_dst = FILE_ACTION_ADDED;
ccc71be50bb49efb4e31004c77fb3e065e9c0596Gordon Ross }
ccc71be50bb49efb4e31004c77fb3e065e9c0596Gordon Ross smb_node_notify_change(src_dnode, a_src, src_fnode->od_name);
ccc71be50bb49efb4e31004c77fb3e065e9c0596Gordon Ross smb_node_notify_change(dst_dnode, a_dst, new_name);
ccc71be50bb49efb4e31004c77fb3e065e9c0596Gordon Ross }
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown
ccc71be50bb49efb4e31004c77fb3e065e9c0596Gordon Ross smb_rename_release_src(sr);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown if (dst_fqi->fq_fnode) {
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown smb_node_end_crit(dst_fnode);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown smb_node_release(dst_fnode);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown }
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown smb_node_release(dst_dnode);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown return (rc);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown}
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown/*
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown * smb_rename_check_stream
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown *
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown * For a stream rename the dst path must begin with ':', or "\\:".
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown * We don't yet support stream rename, Return EACCES.
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown *
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown * If not a stream rename, in accordance with the above rule,
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown * it is not valid for either the src or dst to be a stream.
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown * Return EINVAL.
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown */
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brownstatic int
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brownsmb_rename_check_stream(smb_fqi_t *src_fqi, smb_fqi_t *dst_fqi)
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown{
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown smb_node_t *src_fnode = src_fqi->fq_fnode;
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown char *src_path = src_fqi->fq_path.pn_path;
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown char *dst_path = dst_fqi->fq_path.pn_path;
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown /* We do not yet support named stream rename - ACCESS DENIED */
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown if ((dst_path[0] == ':') ||
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown ((dst_path[0] == '\\') && (dst_path[1] == ':'))) {
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown return (EACCES);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown }
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown /*
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown * If not stream rename (above) neither src or dst can be
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown * a named stream.
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown */
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown if (smb_is_stream_name(dst_path))
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown return (EINVAL);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown if (src_fqi->fq_fnode) {
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown if (SMB_IS_STREAM(src_fnode))
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown return (EINVAL);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown } else {
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown if (smb_is_stream_name(src_path))
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown return (EINVAL);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown }
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown return (0);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown}
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown
b1352070d318187b41b088da3533692976f3f225Alan Wright/*
b1352070d318187b41b088da3533692976f3f225Alan Wright * smb_make_link
b1352070d318187b41b088da3533692976f3f225Alan Wright *
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown * Creating a hard link (adding an additional name) 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 *
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown * If the file is a symlink we create the hardlink on the target
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown * of the symlink (i.e. use SMB_FOLLOW_LINKS when looking up src).
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown * If the target of the symlink does not exist we fail with ENOENT.
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown *
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{
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown smb_node_t *tnode;
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown char *path;
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown int rc;
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown /* Cannnot create link on named stream */
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown if (smb_is_stream_name(src_fqi->fq_path.pn_path) ||
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown smb_is_stream_name(dst_fqi->fq_path.pn_path)) {
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown return (EINVAL);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown }
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown /* lookup and validate src node */
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown rc = smb_rename_lookup_src(sr);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown if (rc != 0)
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown return (rc);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown /* if src and dest paths match we're done */
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown if (smb_strcasecmp(src_fqi->fq_path.pn_path,
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown dst_fqi->fq_path.pn_path, 0) == 0) {
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown smb_rename_release_src(sr);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown return (0);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown }
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown /* find the destination dnode and last_comp */
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown tnode = sr->tid_tree->t_snode;
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown path = dst_fqi->fq_path.pn_path;
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown rc = smb_pathname_reduce(sr, sr->user_cr, path, tnode, tnode,
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown &dst_fqi->fq_dnode, dst_fqi->fq_last_comp);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown if (rc != 0) {
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown smb_rename_release_src(sr);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown return (rc);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown }
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown /* If name match in same directory, we're done */
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown if ((src_fqi->fq_dnode == dst_fqi->fq_dnode) &&
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown (smb_strcasecmp(src_fqi->fq_fnode->od_name,
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown dst_fqi->fq_last_comp, 0) == 0)) {
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown smb_rename_release_src(sr);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown smb_node_release(dst_fqi->fq_dnode);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown return (0);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown }
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier if (smb_is_invalid_filename(dst_fqi->fq_last_comp)) {
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier smb_rename_release_src(sr);
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier smb_node_release(dst_fqi->fq_dnode);
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier return (EILSEQ); /* NT_STATUS_INVALID_OBJECT_NAME */
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier }
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown /* Lookup the destination node. It MUST NOT exist. */
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown rc = smb_fsop_lookup(sr, sr->user_cr, 0, tnode,
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown dst_fqi->fq_dnode, dst_fqi->fq_last_comp, &dst_fqi->fq_fnode);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown if (rc == 0) {
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown smb_node_release(dst_fqi->fq_fnode);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown rc = EEXIST;
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown }
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown if (rc != ENOENT) {
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown smb_rename_release_src(sr);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown smb_node_release(dst_fqi->fq_dnode);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown return (rc);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown }
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown rc = smb_fsop_link(sr, sr->user_cr, src_fqi->fq_fnode,
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown dst_fqi->fq_dnode, dst_fqi->fq_last_comp);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown
ccc71be50bb49efb4e31004c77fb3e065e9c0596Gordon Ross if (rc == 0) {
ccc71be50bb49efb4e31004c77fb3e065e9c0596Gordon Ross smb_node_notify_change(dst_fqi->fq_dnode,
ccc71be50bb49efb4e31004c77fb3e065e9c0596Gordon Ross FILE_ACTION_ADDED, dst_fqi->fq_last_comp);
ccc71be50bb49efb4e31004c77fb3e065e9c0596Gordon Ross }
ccc71be50bb49efb4e31004c77fb3e065e9c0596Gordon Ross
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown smb_rename_release_src(sr);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown smb_node_release(dst_fqi->fq_dnode);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown return (rc);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown}
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown/*
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown * smb_rename_lookup_src
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown *
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown * Lookup the src node, checking for sharing violations and
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh * breaking any existing BATCH oplock.
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown * Populate sr->arg.dirop.fqi
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown *
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown * Upon success, the dnode and fnode will have holds and the
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown * fnode will be in a critical section. These should be
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown * released using smb_rename_release_src().
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown *
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown * Returns errno values.
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown */
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brownstatic int
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brownsmb_rename_lookup_src(smb_request_t *sr)
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown{
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown smb_node_t *src_node, *tnode;
b1352070d318187b41b088da3533692976f3f225Alan Wright DWORD status;
b1352070d318187b41b088da3533692976f3f225Alan Wright int rc;
b1352070d318187b41b088da3533692976f3f225Alan Wright int count;
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desai char *path;
b1352070d318187b41b088da3533692976f3f225Alan Wright
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown struct dirop *dirop = &sr->arg.dirop;
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown smb_fqi_t *src_fqi = &sr->arg.dirop.fqi;
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown if (smb_is_stream_name(src_fqi->fq_path.pn_path))
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown return (EINVAL);
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desai
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown /* Lookup the source node */
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown tnode = sr->tid_tree->t_snode;
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desai path = src_fqi->fq_path.pn_path;
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desai rc = smb_pathname_reduce(sr, sr->user_cr, path, tnode, tnode,
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desai &src_fqi->fq_dnode, src_fqi->fq_last_comp);
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desai if (rc != 0)
b1352070d318187b41b088da3533692976f3f225Alan Wright return (rc);
b1352070d318187b41b088da3533692976f3f225Alan Wright
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown rc = smb_fsop_lookup(sr, sr->user_cr, 0, tnode,
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desai src_fqi->fq_dnode, src_fqi->fq_last_comp, &src_fqi->fq_fnode);
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desai if (rc != 0) {
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desai smb_node_release(src_fqi->fq_dnode);
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desai return (rc);
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desai }
b1352070d318187b41b088da3533692976f3f225Alan Wright
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown /* Not valid to create hardlink for directory */
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown if ((dirop->info_level == SMB_NT_RENAME_SET_LINK_INFO) &&
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown (smb_node_is_dir(src_fqi->fq_fnode))) {
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown smb_node_release(src_fqi->fq_fnode);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown smb_node_release(src_fqi->fq_dnode);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown return (EISDIR);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown }
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown src_node = src_fqi->fq_fnode;
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown rc = smb_rename_check_attr(sr, src_node, src_fqi->fq_sattr);
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desai if (rc != 0) {
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desai smb_node_release(src_fqi->fq_fnode);
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desai smb_node_release(src_fqi->fq_dnode);
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desai return (rc);
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desai }
b1352070d318187b41b088da3533692976f3f225Alan Wright
b1352070d318187b41b088da3533692976f3f225Alan Wright /*
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh * Break BATCH 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 */
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh (void) smb_oplock_break(sr, src_node,
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh SMB_OPLOCK_BREAK_TO_LEVEL_II | SMB_OPLOCK_BREAK_BATCH);
b1352070d318187b41b088da3533692976f3f225Alan Wright
b1352070d318187b41b088da3533692976f3f225Alan Wright for (count = 0; count <= 3; count++) {
b1352070d318187b41b088da3533692976f3f225Alan Wright if (count) {
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown smb_node_end_crit(src_node);
b1352070d318187b41b088da3533692976f3f225Alan Wright delay(MSEC_TO_TICK(400));
b1352070d318187b41b088da3533692976f3f225Alan Wright }
b1352070d318187b41b088da3533692976f3f225Alan Wright
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown smb_node_start_crit(src_node, RW_READER);
b1352070d318187b41b088da3533692976f3f225Alan Wright
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown status = smb_node_rename_check(src_node);
b1352070d318187b41b088da3533692976f3f225Alan Wright if (status != NT_STATUS_SHARING_VIOLATION)
b1352070d318187b41b088da3533692976f3f225Alan Wright break;
b1352070d318187b41b088da3533692976f3f225Alan Wright }
b1352070d318187b41b088da3533692976f3f225Alan Wright
b1352070d318187b41b088da3533692976f3f225Alan Wright if (status == NT_STATUS_SHARING_VIOLATION) {
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown smb_node_end_crit(src_node);
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desai smb_node_release(src_fqi->fq_fnode);
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desai smb_node_release(src_fqi->fq_dnode);
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desai return (EPIPE); /* = ERRbadshare */
b1352070d318187b41b088da3533692976f3f225Alan Wright }
b1352070d318187b41b088da3533692976f3f225Alan Wright
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown status = smb_range_check(sr, src_node, 0, UINT64_MAX, B_TRUE);
b1352070d318187b41b088da3533692976f3f225Alan Wright if (status != NT_STATUS_SUCCESS) {
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown smb_node_end_crit(src_node);
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desai smb_node_release(src_fqi->fq_fnode);
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desai smb_node_release(src_fqi->fq_dnode);
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desai return (EACCES);
b1352070d318187b41b088da3533692976f3f225Alan Wright }
b1352070d318187b41b088da3533692976f3f225Alan Wright
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown return (0);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown}
b1352070d318187b41b088da3533692976f3f225Alan Wright
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown/*
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown * smb_rename_release_src
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown */
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brownstatic void
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brownsmb_rename_release_src(smb_request_t *sr)
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown{
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown smb_fqi_t *src_fqi = &sr->arg.dirop.fqi;
b1352070d318187b41b088da3533692976f3f225Alan Wright
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown smb_node_end_crit(src_fqi->fq_fnode);
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desai smb_node_release(src_fqi->fq_fnode);
b1352070d318187b41b088da3533692976f3f225Alan Wright smb_node_release(src_fqi->fq_dnode);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
b1352070d318187b41b088da3533692976f3f225Alan Wright
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown
b1352070d318187b41b088da3533692976f3f225Alan Wrightstatic int
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintoshsmb_rename_check_attr(smb_request_t *sr, smb_node_t *node, uint16_t sattr)
b1352070d318187b41b088da3533692976f3f225Alan Wright{
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh smb_attr_t attr;
b1352070d318187b41b088da3533692976f3f225Alan Wright
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross bzero(&attr, sizeof (attr));
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross attr.sa_mask = SMB_AT_DOSATTR;
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross if (smb_node_getattr(sr, node, kcred, NULL, &attr) != 0)
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross return (EACCES);
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh if ((attr.sa_dosattr & FILE_ATTRIBUTE_HIDDEN) &&
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh !(SMB_SEARCH_HIDDEN(sattr)))
b1352070d318187b41b088da3533692976f3f225Alan Wright return (ESRCH);
b1352070d318187b41b088da3533692976f3f225Alan Wright
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh if ((attr.sa_dosattr & FILE_ATTRIBUTE_SYSTEM) &&
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh !(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 },
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh { EACCES, ERROR_ACCESS_DENIED, NT_STATUS_ACCESS_DENIED },
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown { EISDIR, ERROR_ACCESS_DENIED, NT_STATUS_FILE_IS_A_DIRECTORY },
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh { EIO, ERROR_INTERNAL_ERROR, NT_STATUS_INTERNAL_ERROR }
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}