From: Jeremy Allison Date: Mon, 27 Mar 2023 18:07:07 +0000 (-0700) Subject: s3: smbd: Duplicate smb_file_link_information() hardlink handling as smb2_file_link_i... X-Git-Tag: talloc-2.4.1~1228 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=377c50abe91d05908d37ba81bdbeece37c45ca6c;p=thirdparty%2Fsamba.git s3: smbd: Duplicate smb_file_link_information() hardlink handling as smb2_file_link_information(). We're going to change the SMB2 path handling for DFS and I really don't want to try and mix these changes into the existing smb_file_link_information() code. Signed-off-by: Jeremy Allison Reviewed-by: Ralph Boehme --- diff --git a/source3/smbd/smb2_trans2.c b/source3/smbd/smb2_trans2.c index 089a8f08853..24c21bc16f9 100644 --- a/source3/smbd/smb2_trans2.c +++ b/source3/smbd/smb2_trans2.c @@ -4504,6 +4504,99 @@ static NTSTATUS smb2_file_rename_information(connection_struct *conn, return status; } +static NTSTATUS smb2_file_link_information(connection_struct *conn, + struct smb_request *req, + const char *pdata, + int total_data, + files_struct *fsp, + struct smb_filename *smb_fname_src) +{ + bool overwrite; + uint32_t len; + char *newname = NULL; + struct files_struct *dst_dirfsp = NULL; + struct smb_filename *smb_fname_dst = NULL; + NTSTATUS status = NT_STATUS_OK; + uint32_t ucf_flags = ucf_flags_from_smb_request(req); + NTTIME dst_twrp = 0; + TALLOC_CTX *ctx = talloc_tos(); + + if (!fsp) { + return NT_STATUS_INVALID_HANDLE; + } + + if (total_data < 20) { + return NT_STATUS_INVALID_PARAMETER; + } + + overwrite = (CVAL(pdata,0) ? true : false); + len = IVAL(pdata,16); + + if (len > (total_data - 20) || (len == 0)) { + return NT_STATUS_INVALID_PARAMETER; + } + + if (smb_fname_src->flags & SMB_FILENAME_POSIX_PATH) { + srvstr_get_path_posix(ctx, + pdata, + req->flags2, + &newname, + &pdata[20], + len, + STR_TERMINATE, + &status); + ucf_flags |= UCF_POSIX_PATHNAMES; + } else { + srvstr_get_path(ctx, + pdata, + req->flags2, + &newname, + &pdata[20], + len, + STR_TERMINATE, + &status); + } + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + DBG_DEBUG("got name |%s|\n", newname); + + if (ucf_flags & UCF_GMT_PATHNAME) { + extract_snapshot_token(newname, &dst_twrp); + } + status = filename_convert_dirfsp(ctx, + conn, + newname, + ucf_flags, + dst_twrp, + &dst_dirfsp, + &smb_fname_dst); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (fsp->base_fsp) { + /* No stream names. */ + return NT_STATUS_NOT_SUPPORTED; + } + + DBG_DEBUG("SMB_FILE_LINK_INFORMATION (%s) %s -> %s\n", + fsp_fnum_dbg(fsp), fsp_str_dbg(fsp), + smb_fname_str_dbg(smb_fname_dst)); + status = hardlink_internals(ctx, + conn, + req, + overwrite, + NULL, /* src_dirfsp */ + fsp->fsp_name, + dst_dirfsp, /* dst_dirfsp */ + smb_fname_dst); + + TALLOC_FREE(smb_fname_dst); + return status; +} + static NTSTATUS smb_file_link_information(connection_struct *conn, struct smb_request *req, const char *pdata, @@ -4599,6 +4692,7 @@ static NTSTATUS smb_file_link_information(connection_struct *conn, return status; } + /**************************************************************************** Deal with SMB_FILE_RENAME_INFORMATION. ****************************************************************************/ @@ -5206,9 +5300,21 @@ NTSTATUS smbd_do_setfilepathinfo(connection_struct *conn, case SMB_FILE_LINK_INFORMATION: { - status = smb_file_link_information(conn, req, - pdata, total_data, - fsp, smb_fname); + if (conn->sconn->using_smb2) { + status = smb2_file_link_information(conn, + req, + pdata, + total_data, + fsp, + smb_fname); + } else { + status = smb_file_link_information(conn, + req, + pdata, + total_data, + fsp, + smb_fname); + } break; }