1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-22 22:04:08 +03:00

Implement rename/move in SMB2 from Windows7.

Jeremy.
This commit is contained in:
Jeremy Allison 2010-02-25 11:15:16 -08:00
parent 166a3821c9
commit 3551eb7cbf
3 changed files with 112 additions and 1 deletions

View File

@ -294,6 +294,7 @@ Byte offset Type name description
#define SMB_FILE_ACCESS_INFORMATION 1008
#define SMB_FILE_NAME_INFORMATION 1009
#define SMB_FILE_RENAME_INFORMATION 1010
#define SMB2_FILE_RENAME_INFORMATION_INTERNAL 0xFF0A /* Internal mapped version. */
#define SMB_FILE_LINK_INFORMATION 1011
#define SMB_FILE_NAMES_INFORMATION 1012
#define SMB_FILE_DISPOSITION_INFORMATION 1013

View File

@ -213,7 +213,8 @@ static struct tevent_req *smbd_smb2_setinfo_send(TALLOC_CTX *mem_ctx,
file_info_level = in_file_info_class + 1000;
if (file_info_level == SMB_FILE_RENAME_INFORMATION) {
file_info_level = 0xFF00 + in_file_info_class;
/* SMB2_FILE_RENAME_INFORMATION_INTERNAL == 0xFF00 + in_file_info_class */
file_info_level = SMB2_FILE_RENAME_INFORMATION_INTERNAL;
}
if (fsp->is_directory || fsp->fh->fd == -1) {

View File

@ -5887,6 +5887,107 @@ static NTSTATUS smb_set_file_unix_hlink(connection_struct *conn,
return hardlink_internals(ctx, conn, smb_fname_old, smb_fname_new);
}
/****************************************************************************
Deal with SMB2_FILE_RENAME_INFORMATION_INTERNAL
****************************************************************************/
static NTSTATUS smb2_file_rename_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 smb_filename *smb_fname_dst = NULL;
NTSTATUS status = NT_STATUS_OK;
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;
}
srvstr_get_path(ctx, pdata, req->flags2, &newname,
&pdata[20], len, STR_TERMINATE,
&status);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
DEBUG(10,("smb_file_rename_information: got name |%s|\n",
newname));
#if 0
/* Check the new name has no '/' characters. */
if (strchr_m(newname, '/')) {
return NT_STATUS_NOT_SUPPORTED;
}
#endif
status = filename_convert(ctx,
conn,
req->flags2 & FLAGS2_DFS_PATHNAMES,
newname,
0,
NULL,
&smb_fname_dst);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
if (fsp && fsp->base_fsp) {
/* newname must be a stream name. */
if (newname[0] != ':') {
return NT_STATUS_NOT_SUPPORTED;
}
/* Create an smb_fname to call rename_internals_fsp() with. */
status = create_synthetic_smb_fname(talloc_tos(),
fsp->base_fsp->fsp_name->base_name, newname, NULL,
&smb_fname_dst);
if (!NT_STATUS_IS_OK(status)) {
goto out;
}
/*
* Set the original last component, since
* rename_internals_fsp() requires it.
*/
smb_fname_dst->original_lcomp = talloc_strdup(smb_fname_dst,
newname);
if (smb_fname_dst->original_lcomp == NULL) {
status = NT_STATUS_NO_MEMORY;
goto out;
}
}
DEBUG(10,("smb_file_rename_information: "
"SMB_FILE_RENAME_INFORMATION (fnum %d) %s -> %s\n",
fsp->fnum, fsp_str_dbg(fsp),
smb_fname_str_dbg(smb_fname_dst)));
status = rename_internals_fsp(conn, fsp, smb_fname_dst, 0,
overwrite);
out:
TALLOC_FREE(smb_fname_dst);
return status;
}
/****************************************************************************
Deal with SMB_FILE_RENAME_INFORMATION.
****************************************************************************/
@ -7475,6 +7576,14 @@ NTSTATUS smbd_do_setfilepathinfo(connection_struct *conn,
break;
}
case SMB2_FILE_RENAME_INFORMATION_INTERNAL:
{
/* SMB2 rename information. */
status = smb2_file_rename_information(conn, req,
pdata, total_data,
fsp, smb_fname);
break;
}
#if defined(HAVE_POSIX_ACLS)
case SMB_SET_POSIX_ACL:
{