summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/libcli/raw/interfaces.h5
-rw-r--r--source4/libcli/raw/rawsetfileinfo.c11
-rw-r--r--source4/libcli/smb2/setinfo.c6
-rw-r--r--source4/ntvfs/posix/pvfs_setfileinfo.c3
-rw-r--r--source4/smb_server/blob.c38
-rw-r--r--source4/smb_server/smb2/fileinfo.c5
6 files changed, 54 insertions, 14 deletions
diff --git a/source4/libcli/raw/interfaces.h b/source4/libcli/raw/interfaces.h
index 16db17d7ab..24e8ad4afc 100644
--- a/source4/libcli/raw/interfaces.h
+++ b/source4/libcli/raw/interfaces.h
@@ -902,7 +902,10 @@ enum smb_setfileinfo_level {
RAW_SFILEINFO_1029 = SMB_SFILEINFO_1029,
RAW_SFILEINFO_1032 = SMB_SFILEINFO_1032,
RAW_SFILEINFO_1039 = SMB_SFILEINFO_1039,
- RAW_SFILEINFO_1040 = SMB_SFILEINFO_1040
+ RAW_SFILEINFO_1040 = SMB_SFILEINFO_1040,
+
+ /* cope with breakage in SMB2 */
+ RAW_SFILEINFO_RENAME_INFORMATION_SMB2 = SMB_SFILEINFO_RENAME_INFORMATION|0x80000000,
};
/* union used in setfileinfo() and setpathinfo() calls */
diff --git a/source4/libcli/raw/rawsetfileinfo.c b/source4/libcli/raw/rawsetfileinfo.c
index a9a1a3547e..f1e4ee3686 100644
--- a/source4/libcli/raw/rawsetfileinfo.c
+++ b/source4/libcli/raw/rawsetfileinfo.c
@@ -75,6 +75,16 @@ bool smb_raw_setfileinfo_passthru(TALLOC_CTX *mem_ctx,
SIVAL(blob->data, 8, len - 2);
return true;
+ case RAW_SFILEINFO_RENAME_INFORMATION_SMB2:
+ NEED_BLOB(20);
+ SIVAL(blob->data, 0, parms->rename_information.in.overwrite);
+ SBVAL(blob->data, 8, parms->rename_information.in.root_fid);
+ len = smbcli_blob_append_string(NULL, mem_ctx, blob,
+ parms->rename_information.in.new_name,
+ STR_UNICODE|STR_TERMINATE);
+ SIVAL(blob->data, 16, len - 2);
+ return true;
+
case RAW_SFILEINFO_POSITION_INFORMATION:
NEED_BLOB(8);
SBVAL(blob->data, 0, parms->position_information.in.position);
@@ -229,6 +239,7 @@ static bool smb_raw_setinfo_backend(struct smbcli_tree *tree,
case RAW_SFILEINFO_UNIX_LINK:
case RAW_SFILEINFO_UNIX_HLINK:
+ case RAW_SFILEINFO_RENAME_INFORMATION_SMB2:
break;
}
diff --git a/source4/libcli/smb2/setinfo.c b/source4/libcli/smb2/setinfo.c
index d942568a2d..a6e22d9a68 100644
--- a/source4/libcli/smb2/setinfo.c
+++ b/source4/libcli/smb2/setinfo.c
@@ -92,6 +92,12 @@ struct smb2_request *smb2_setinfo_file_send(struct smb2_tree *tree, union smb_se
ZERO_STRUCT(b);
b.in.level = smb2_level;
b.in.file.handle = io->generic.in.file.handle;
+
+ /* change levels so the parsers know it is SMB2 */
+ if (io->generic.level == RAW_SFILEINFO_RENAME_INFORMATION) {
+ io->generic.level = RAW_SFILEINFO_RENAME_INFORMATION_SMB2;
+ }
+
if (!smb_raw_setfileinfo_passthru(tree, io->generic.level, io, &b.in.blob)) {
return NULL;
}
diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c
index ce977873c8..9c78699edb 100644
--- a/source4/ntvfs/posix/pvfs_setfileinfo.c
+++ b/source4/ntvfs/posix/pvfs_setfileinfo.c
@@ -64,6 +64,7 @@ static uint32_t pvfs_setfileinfo_access(union smb_setfileinfo *info)
break;
case RAW_SFILEINFO_RENAME_INFORMATION:
+ case RAW_SFILEINFO_RENAME_INFORMATION_SMB2:
needed = SEC_STD_DELETE;
break;
@@ -382,6 +383,7 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs,
break;
case RAW_SFILEINFO_RENAME_INFORMATION:
+ case RAW_SFILEINFO_RENAME_INFORMATION_SMB2:
return pvfs_setfileinfo_rename(pvfs, req, h->name,
info);
@@ -579,6 +581,7 @@ NTSTATUS pvfs_setpathinfo(struct ntvfs_module_context *ntvfs,
return NT_STATUS_OK;
case RAW_SFILEINFO_RENAME_INFORMATION:
+ case RAW_SFILEINFO_RENAME_INFORMATION_SMB2:
return pvfs_setfileinfo_rename(pvfs, req, name,
info);
diff --git a/source4/smb_server/blob.c b/source4/smb_server/blob.c
index 795e7ce585..8c813204f3 100644
--- a/source4/smb_server/blob.c
+++ b/source4/smb_server/blob.c
@@ -563,20 +563,32 @@ NTSTATUS smbsrv_pull_passthru_sfileinfo(TALLOC_CTX *mem_ctx,
if (!bufinfo) {
return NT_STATUS_INTERNAL_ERROR;
}
- if (bufinfo->flags & BUFINFO_FLAG_SMB2) {
- /* SMB2 uses a different format for rename information */
- BLOB_CHECK_MIN_SIZE(blob, 20);
- st->rename_information.in.overwrite = CVAL(blob->data, 0);
- st->rename_information.in.root_fid = BVAL(blob->data, 4);
- len = IVAL(blob->data,16);
- ofs = 20;
- } else {
- BLOB_CHECK_MIN_SIZE(blob, 12);
- st->rename_information.in.overwrite = CVAL(blob->data, 0);
- st->rename_information.in.root_fid = IVAL(blob->data, 4);
- len = IVAL(blob->data, 8);
- ofs = 12;
+ BLOB_CHECK_MIN_SIZE(blob, 12);
+ st->rename_information.in.overwrite = CVAL(blob->data, 0);
+ st->rename_information.in.root_fid = IVAL(blob->data, 4);
+ len = IVAL(blob->data, 8);
+ ofs = 12;
+ str_blob = *blob;
+ str_blob.length = MIN(str_blob.length, ofs+len);
+ smbsrv_blob_pull_string(bufinfo, &str_blob, ofs,
+ &st->rename_information.in.new_name,
+ STR_UNICODE);
+ if (st->rename_information.in.new_name == NULL) {
+ return NT_STATUS_FOOBAR;
+ }
+
+ return NT_STATUS_OK;
+
+ case RAW_SFILEINFO_RENAME_INFORMATION_SMB2:
+ /* SMB2 uses a different format for rename information */
+ if (!bufinfo) {
+ return NT_STATUS_INTERNAL_ERROR;
}
+ BLOB_CHECK_MIN_SIZE(blob, 20);
+ st->rename_information.in.overwrite = CVAL(blob->data, 0);
+ st->rename_information.in.root_fid = BVAL(blob->data, 8);
+ len = IVAL(blob->data,16);
+ ofs = 20;
str_blob = *blob;
str_blob.length = MIN(str_blob.length, ofs+len);
smbsrv_blob_pull_string(bufinfo, &str_blob, ofs,
diff --git a/source4/smb_server/smb2/fileinfo.c b/source4/smb_server/smb2/fileinfo.c
index e375b7308f..e6521991ef 100644
--- a/source4/smb_server/smb2/fileinfo.c
+++ b/source4/smb_server/smb2/fileinfo.c
@@ -266,6 +266,11 @@ static NTSTATUS smb2srv_setinfo_file(struct smb2srv_setinfo_op *op, uint8_t smb2
io->generic.level = smb2_level + 1000;
io->generic.in.file.ntvfs = op->info->in.file.ntvfs;
+ /* handle cases that don't map directly */
+ if (io->generic.level == RAW_SFILEINFO_RENAME_INFORMATION) {
+ io->generic.level = RAW_SFILEINFO_RENAME_INFORMATION_SMB2;
+ }
+
status = smbsrv_pull_passthru_sfileinfo(io, io->generic.level, io,
&op->info->in.blob,
STR_UNICODE, &op->req->in.bufinfo);