[PATCH] Fix bug 13140 - smbclient volume command is missing in SMB2.
Jeremy Allison
jra at samba.org
Wed Nov 15 00:00:24 UTC 2017
Applies after the fix for bug:
https://bugzilla.samba.org/show_bug.cgi?id=13138
Includes regression test.
Please review and push if happy !
Cheers,
Jeremy.
-------------- next part --------------
From b26e6a152c1a4981c884c58373ebbd11f6252da8 Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Tue, 14 Nov 2017 15:42:14 -0800
Subject: [PATCH 1/2] s3: smbclient: Implement "volume" command over SMB2.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13140
Signed-off-by: Jeremy Allison <jra at samba.org>
---
source3/libsmb/cli_smb2_fnum.c | 129 +++++++++++++++++++++++++++++++++++++++++
source3/libsmb/cli_smb2_fnum.h | 5 ++
source3/libsmb/clifsinfo.c | 8 +++
3 files changed, 142 insertions(+)
diff --git a/source3/libsmb/cli_smb2_fnum.c b/source3/libsmb/cli_smb2_fnum.c
index ed6cdd4a1e6..628b17b293b 100644
--- a/source3/libsmb/cli_smb2_fnum.c
+++ b/source3/libsmb/cli_smb2_fnum.c
@@ -2168,6 +2168,135 @@ fail:
return status;
}
+/***************************************************************
+ Wrapper that allows SMB2 to query file system volume info.
+ Synchronous only.
+***************************************************************/
+
+NTSTATUS cli_smb2_get_fs_volume_info(struct cli_state *cli,
+ TALLOC_CTX *mem_ctx,
+ char **_volume_name,
+ uint32_t *pserial_number,
+ time_t *pdate)
+{
+ NTSTATUS status;
+ uint16_t fnum = 0xffff;
+ DATA_BLOB outbuf = data_blob_null;
+ struct smb2_hnd *ph = NULL;
+ uint32_t nlen;
+ char *volume_name = NULL;
+ TALLOC_CTX *frame = talloc_stackframe();
+
+ if (smbXcli_conn_has_async_calls(cli->conn)) {
+ /*
+ * Can't use sync call while an async call is in flight
+ */
+ status = NT_STATUS_INVALID_PARAMETER;
+ goto fail;
+ }
+
+ if (smbXcli_conn_protocol(cli->conn) < PROTOCOL_SMB2_02) {
+ status = NT_STATUS_INVALID_PARAMETER;
+ goto fail;
+ }
+
+ /* First open the top level directory. */
+ status =
+ cli_smb2_create_fnum(cli, "", 0, /* create_flags */
+ FILE_READ_ATTRIBUTES, /* desired_access */
+ FILE_ATTRIBUTE_DIRECTORY, /* file attributes */
+ FILE_SHARE_READ | FILE_SHARE_WRITE |
+ FILE_SHARE_DELETE, /* share_access */
+ FILE_OPEN, /* create_disposition */
+ FILE_DIRECTORY_FILE, /* create_options */
+ &fnum,
+ NULL);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ goto fail;
+ }
+
+ status = map_fnum_to_smb2_handle(cli, fnum, &ph);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto fail;
+ }
+
+ /* getinfo on the returned handle with info_type SMB2_GETINFO_FS (2),
+ level 1 (SMB_FS_VOLUME_INFORMATION). */
+
+ status = smb2cli_query_info(cli->conn,
+ cli->timeout,
+ cli->smb2.session,
+ cli->smb2.tcon,
+ SMB2_GETINFO_FS, /* in_info_type */
+ /* in_file_info_class */
+ SMB_FS_VOLUME_INFORMATION - 1000,
+ 0xFFFF, /* in_max_output_length */
+ NULL, /* in_input_buffer */
+ 0, /* in_additional_info */
+ 0, /* in_flags */
+ ph->fid_persistent,
+ ph->fid_volatile,
+ frame,
+ &outbuf);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto fail;
+ }
+
+ if (outbuf.length < 24) {
+ status = NT_STATUS_INVALID_NETWORK_RESPONSE;
+ goto fail;
+ }
+
+ if (pdate) {
+ struct timespec ts;
+ ts = interpret_long_date((char *)outbuf.data);
+ *pdate = ts.tv_sec;
+ }
+ if (pserial_number) {
+ *pserial_number = IVAL(outbuf.data,8);
+ }
+ nlen = IVAL(outbuf.data,12);
+ if (nlen + 18 < 18) {
+ /* Integer wrap. */
+ status = NT_STATUS_INVALID_NETWORK_RESPONSE;
+ goto fail;
+ }
+ /*
+ * The next check is safe as we know outbuf.length >= 24
+ * from above.
+ */
+ if (nlen > (outbuf.length - 18)) {
+ status = NT_STATUS_INVALID_NETWORK_RESPONSE;
+ goto fail;
+ }
+
+ clistr_pull_talloc(mem_ctx,
+ (const char *)outbuf.data,
+ 0,
+ &volume_name,
+ outbuf.data + 18,
+ nlen,
+ STR_UNICODE);
+ if (volume_name == NULL) {
+ status = map_nt_error_from_unix(errno);
+ goto fail;
+ }
+
+ *_volume_name = volume_name;
+
+fail:
+
+ if (fnum != 0xffff) {
+ cli_smb2_close_fnum(cli, fnum);
+ }
+
+ cli->raw_status = status;
+
+ TALLOC_FREE(frame);
+ return status;
+}
+
/***************************************************************
Wrapper that allows SMB2 to query a security descriptor.
diff --git a/source3/libsmb/cli_smb2_fnum.h b/source3/libsmb/cli_smb2_fnum.h
index 793efc719ea..3d9b6eb3fe6 100644
--- a/source3/libsmb/cli_smb2_fnum.h
+++ b/source3/libsmb/cli_smb2_fnum.h
@@ -142,6 +142,11 @@ NTSTATUS cli_smb2_get_fs_full_size_info(struct cli_state *cli,
uint64_t *actual_allocation_units,
uint64_t *sectors_per_allocation_unit,
uint64_t *bytes_per_sector);
+NTSTATUS cli_smb2_get_fs_volume_info(struct cli_state *cli,
+ TALLOC_CTX *mem_ctx,
+ char **_volume_name,
+ uint32_t *pserial_number,
+ time_t *pdate);
NTSTATUS cli_smb2_query_security_descriptor(struct cli_state *cli,
uint16_t fnum,
uint32_t sec_info,
diff --git a/source3/libsmb/clifsinfo.c b/source3/libsmb/clifsinfo.c
index 46236390022..09c0d9535f1 100644
--- a/source3/libsmb/clifsinfo.c
+++ b/source3/libsmb/clifsinfo.c
@@ -375,6 +375,14 @@ NTSTATUS cli_get_fs_volume_info(struct cli_state *cli,
unsigned int nlen;
char *volume_name = NULL;
+ if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
+ return cli_smb2_get_fs_volume_info(cli,
+ mem_ctx,
+ _volume_name,
+ pserial_number,
+ pdate);
+ }
+
SSVAL(setup, 0, TRANSACT2_QFSINFO);
SSVAL(param,0,SMB_QUERY_FS_VOLUME_INFO);
--
2.15.0.448.gf294e3d99a-goog
From 5e346cf2c3e94b540eea9570381a7673e390e8dd Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Tue, 14 Nov 2017 15:54:19 -0800
Subject: [PATCH 2/2] s3: smbclient: tests: Test "volume" command over SMB1 and
SMB2+.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13140
Signed-off-by: Jeremy Allison <jra at samba.org>
---
source3/script/tests/test_smbclient_s3.sh | 31 +++++++++++++++++++++++++++++++
1 file changed, 31 insertions(+)
diff --git a/source3/script/tests/test_smbclient_s3.sh b/source3/script/tests/test_smbclient_s3.sh
index 45005776cf8..d98da0dd260 100755
--- a/source3/script/tests/test_smbclient_s3.sh
+++ b/source3/script/tests/test_smbclient_s3.sh
@@ -1525,7 +1525,34 @@ EOF
fi
}
+# Test doing a volume command.
+test_volume()
+{
+ tmpfile=$PREFIX/smbclient_interactive_prompt_commands
+ cat > $tmpfile <<EOF
+volume
+quit
+EOF
+ cmd='CLI_FORCE_INTERACTIVE=yes $SMBCLIENT "$@" -U$USERNAME%$PASSWORD //$SERVER/tmp -I $SERVER_IP $ADDARGS < $tmpfile 2>&1'
+ eval echo "$cmd"
+ out=`eval $cmd`
+ ret=$?
+ rm -f $tmpfile
+ if [ $ret != 0 ] ; then
+ echo "$out"
+ echo "failed doing volume command with error $ret"
+ return 1
+ fi
+
+ echo "$out" | grep '^Volume: |tmp| serial number'
+ ret=$?
+ if [ $ret != 0 ] ; then
+ echo "$out"
+ echo "failed doing volume command"
+ return 1
+ fi
+}
test_server_os_message()
{
@@ -1684,6 +1711,10 @@ testit "rename_dotdot" \
test_rename_dotdot || \
failed=`expr $failed + 1`
+testit "volume" \
+ test_volume || \
+ failed=`expr $failed + 1`
+
testit "rm -rf $LOGDIR" \
rm -rf $LOGDIR || \
failed=`expr $failed + 1`
--
2.15.0.448.gf294e3d99a-goog
More information about the samba-technical
mailing list