From ea41aa636bc6d1d296339f3cd58e2a3f8a43e98d Mon Sep 17 00:00:00 2001 From: Jeremy Allison 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 Reviewed-by: Andreas Schneider (cherry picked from commit aaa52ab7b5ae711b80e3967ab1ecc91888c346f6) --- source3/libsmb/cli_smb2_fnum.c | 130 +++++++++++++++++++++++++++++++++++++++++ source3/libsmb/cli_smb2_fnum.h | 5 ++ source3/libsmb/clifsinfo.c | 8 +++ 3 files changed, 143 insertions(+) diff --git a/source3/libsmb/cli_smb2_fnum.c b/source3/libsmb/cli_smb2_fnum.c index 89cb1f479d5..5d46d543002 100644 --- a/source3/libsmb/cli_smb2_fnum.c +++ b/source3/libsmb/cli_smb2_fnum.c @@ -2168,6 +2168,136 @@ 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. Synchronous only. diff --git a/source3/libsmb/cli_smb2_fnum.h b/source3/libsmb/cli_smb2_fnum.h index c9325b66902..7b9026e92d3 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 e7842c19ef8acd5ccebe30475a46fe4cba4896ac Mon Sep 17 00:00:00 2001 From: Jeremy Allison 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 Reviewed-by: Andreas Schneider Autobuild-User(master): Andreas Schneider Autobuild-Date(master): Wed Nov 15 19:50:54 CET 2017 on sn-devel-144 (cherry picked from commit f8cd211acc3824e01d89a6f8b6666c39aa5cd54e) --- source3/script/tests/test_smbclient_s3.sh | 32 +++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/source3/script/tests/test_smbclient_s3.sh b/source3/script/tests/test_smbclient_s3.sh index db598a35326..905da581a88 100755 --- a/source3/script/tests/test_smbclient_s3.sh +++ b/source3/script/tests/test_smbclient_s3.sh @@ -1458,6 +1458,34 @@ EOF fi } +# Test doing a volume command. +test_volume() +{ + tmpfile=$PREFIX/smbclient_interactive_prompt_commands + cat > $tmpfile <