[PATCH] Fix smbclient to use modern (trans2/SMB1) disk size calls.
Jeremy Allison
jra at samba.org
Thu Jun 5 12:19:16 MDT 2014
Based on the request for Xerox, here is
a short patchset to update smbclient to
request disk sizes for SMB1 via a more
modern trans2 call rather than the (now
obsolete for EMC :-) core protocol call.
Part #1: Create new 64-bit cli_disk_size() call.
Initially based on top of the old cli_dskattr()
call. Move the 2 users of cli_dskattr() to the
new call.
Part #2: Widen cli_smb2_dskattr() to a 64-bit
interface (compatible with cli_disk_size()).
Part #3: Change cli_disk_size() to call the
existing cli_get_fs_full_size_info() call
for SMB1 (use cli_smb2_dskattr() as before
for SMB2) and only fall back to cli_dskattr()
if cli_get_fs_full_size_info() is unsupported.
As cli_get_fs_full_size_info() is used by
libsmbclient() this is already safe to
use.
Please review and/or push !
Thanks,
Jeremy.
-------------- next part --------------
From 7b727274117e0180892bbba778c41b6a36a8b9fe Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Wed, 4 Jun 2014 14:12:38 -0700
Subject: [PATCH 1/3] s3: libsmb : Move users of cli_dskattr to a 64-bit
interface cli_disk_free().
Signed-off-by: Jeremy Allison <jra at samba.org>
---
source3/client/client.c | 10 ++++++----
source3/libsmb/clifile.c | 26 ++++++++++++++++++++++++++
source3/libsmb/proto.h | 1 +
source3/torture/nbio.c | 4 ++--
4 files changed, 35 insertions(+), 6 deletions(-)
diff --git a/source3/client/client.c b/source3/client/client.c
index 592258d..17985b9 100644
--- a/source3/client/client.c
+++ b/source3/client/client.c
@@ -298,7 +298,7 @@ static void send_message(const char *username)
static int do_dskattr(void)
{
- int total, bsize, avail;
+ uint64_t total, bsize, avail;
struct cli_state *targetcli = NULL;
char *targetpath = NULL;
TALLOC_CTX *ctx = talloc_tos();
@@ -312,14 +312,16 @@ static int do_dskattr(void)
return 1;
}
- status = cli_dskattr(targetcli, &bsize, &total, &avail);
+ status = cli_disk_size(targetcli, &bsize, &total, &avail);
if (!NT_STATUS_IS_OK(status)) {
d_printf("Error in dskattr: %s\n", nt_errstr(status));
return 1;
}
- d_printf("\n\t\t%d blocks of size %d. %d blocks available\n",
- total, bsize, avail);
+ d_printf("\n\t\t%" PRIu64
+ " blocks of size %" PRIu64
+ ". %" PRIu64 " blocks available\n",
+ total, bsize, avail);
return 0;
}
diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c
index 70b769d..8bb1512 100644
--- a/source3/libsmb/clifile.c
+++ b/source3/libsmb/clifile.c
@@ -4132,6 +4132,32 @@ NTSTATUS cli_dskattr(struct cli_state *cli, int *bsize, int *total, int *avail)
return status;
}
+NTSTATUS cli_disk_size(struct cli_state *cli, uint64_t *bsize, uint64_t *total, uint64_t *avail)
+{
+ int old_bsize, old_total, old_avail;
+ NTSTATUS status;
+
+ if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
+ status = cli_smb2_dskattr(cli, &old_bsize, &old_total, &old_avail);
+ } else {
+ status = cli_dskattr(cli, &old_bsize, &old_total, &old_avail);
+ }
+
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+ if (bsize) {
+ *bsize = (uint64_t)old_bsize;
+ }
+ if (total) {
+ *total = (uint64_t)old_total;
+ }
+ if (avail) {
+ *avail = (uint64_t)old_avail;
+ }
+ return NT_STATUS_OK;
+}
+
/****************************************************************************
Create and open a temporary file.
****************************************************************************/
diff --git a/source3/libsmb/proto.h b/source3/libsmb/proto.h
index 525625c..63d2df4 100644
--- a/source3/libsmb/proto.h
+++ b/source3/libsmb/proto.h
@@ -516,6 +516,7 @@ struct tevent_req *cli_dskattr_send(TALLOC_CTX *mem_ctx,
NTSTATUS cli_dskattr_recv(struct tevent_req *req, int *bsize, int *total,
int *avail);
NTSTATUS cli_dskattr(struct cli_state *cli, int *bsize, int *total, int *avail);
+NTSTATUS cli_disk_size(struct cli_state *cli, uint64_t *bsize, uint64_t *total, uint64_t *avail);
struct tevent_req *cli_ctemp_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
struct cli_state *cli,
diff --git a/source3/torture/nbio.c b/source3/torture/nbio.c
index ba4fa95..55dd836 100644
--- a/source3/torture/nbio.c
+++ b/source3/torture/nbio.c
@@ -285,9 +285,9 @@ void nb_qfileinfo(int fnum)
void nb_qfsinfo(int level)
{
- int bsize, total, avail;
+ uint64_t bsize, total, avail;
/* this is not the right call - we need cli_qfsinfo() */
- cli_dskattr(c, &bsize, &total, &avail);
+ cli_disk_size(c, &bsize, &total, &avail);
}
static NTSTATUS find_fn(const char *mnt, struct file_info *finfo, const char *name,
--
2.0.0.526.g5318336
From 8e37aa814741d26f644f04febe7a56d6d4f54791 Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Wed, 4 Jun 2014 14:19:30 -0700
Subject: [PATCH 2/3] s3: libsmb: Make cli_smb2_dskattr() a 64-bit interface.
Remove the fallback call from cli_dskattr() (now it's
not called from external client code).
Signed-off-by: Jeremy Allison <jra at samba.org>
---
source3/libsmb/cli_smb2_fnum.c | 8 ++++----
source3/libsmb/cli_smb2_fnum.h | 6 +++---
source3/libsmb/clifile.c | 10 +++-------
3 files changed, 10 insertions(+), 14 deletions(-)
diff --git a/source3/libsmb/cli_smb2_fnum.c b/source3/libsmb/cli_smb2_fnum.c
index 8eb776a..950398a 100644
--- a/source3/libsmb/cli_smb2_fnum.c
+++ b/source3/libsmb/cli_smb2_fnum.c
@@ -1411,7 +1411,7 @@ NTSTATUS cli_smb2_setattrE(struct cli_state *cli,
Synchronous only.
***************************************************************/
-NTSTATUS cli_smb2_dskattr(struct cli_state *cli, int *bsize, int *total, int *avail)
+NTSTATUS cli_smb2_dskattr(struct cli_state *cli, uint64_t *bsize, uint64_t *total, uint64_t *avail)
{
NTSTATUS status;
uint16_t fnum = 0xffff;
@@ -1492,13 +1492,13 @@ NTSTATUS cli_smb2_dskattr(struct cli_state *cli, int *bsize, int *total, int *av
bytes_per_sector = IVAL(outbuf.data, 20);
if (bsize) {
- *bsize = (int)(sectors_per_unit * bytes_per_sector);
+ *bsize = (uint64_t)sectors_per_unit * (uint64_t)bytes_per_sector;
}
if (total) {
- *total = (int)total_size;
+ *total = total_size;
}
if (avail) {
- *avail = (int)size_free;
+ *avail = size_free;
}
status = NT_STATUS_OK;
diff --git a/source3/libsmb/cli_smb2_fnum.h b/source3/libsmb/cli_smb2_fnum.h
index 61a0f68..a5ed5a0 100644
--- a/source3/libsmb/cli_smb2_fnum.h
+++ b/source3/libsmb/cli_smb2_fnum.h
@@ -100,9 +100,9 @@ NTSTATUS cli_smb2_setattrE(struct cli_state *cli,
time_t access_time,
time_t write_time);
NTSTATUS cli_smb2_dskattr(struct cli_state *cli,
- int *bsize,
- int *total,
- int *avail);
+ uint64_t *bsize,
+ uint64_t *total,
+ uint64_t *avail);
NTSTATUS cli_smb2_query_security_descriptor(struct cli_state *cli,
uint16_t fnum,
uint32_t sec_info,
diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c
index 8bb1512..18ed529 100644
--- a/source3/libsmb/clifile.c
+++ b/source3/libsmb/clifile.c
@@ -4094,10 +4094,6 @@ NTSTATUS cli_dskattr(struct cli_state *cli, int *bsize, int *total, int *avail)
struct tevent_req *req = NULL;
NTSTATUS status = NT_STATUS_OK;
- if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
- return cli_smb2_dskattr(cli, bsize, total, avail);
- }
-
frame = talloc_stackframe();
if (smbXcli_conn_has_async_calls(cli->conn)) {
@@ -4138,11 +4134,11 @@ NTSTATUS cli_disk_size(struct cli_state *cli, uint64_t *bsize, uint64_t *total,
NTSTATUS status;
if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
- status = cli_smb2_dskattr(cli, &old_bsize, &old_total, &old_avail);
- } else {
- status = cli_dskattr(cli, &old_bsize, &old_total, &old_avail);
+ return cli_smb2_dskattr(cli, bsize, total, avail);
}
+ /* Old SMB1 core protocol fallback. */
+ status = cli_dskattr(cli, &old_bsize, &old_total, &old_avail);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
--
2.0.0.526.g5318336
From c7cd02e62074713a077df0d559565c1927c529ba Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Wed, 4 Jun 2014 14:53:01 -0700
Subject: [PATCH 3/3] s3: libsmb: Change cli_disk_size() to use the
trans2/SMB_FS_FULL_SIZE_INFORMATION call in preference to the old SMB1 call.
Fallback to the old CORE protocol SMBdskattr if
trans2/SMB_FS_FULL_SIZE_INFORMATION is not supported.
Signed-off-by: Jeremy Allison <jra at samba.org>
---
source3/libsmb/clifile.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 45 insertions(+)
diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c
index 18ed529..1c52730 100644
--- a/source3/libsmb/clifile.c
+++ b/source3/libsmb/clifile.c
@@ -4130,6 +4130,8 @@ NTSTATUS cli_dskattr(struct cli_state *cli, int *bsize, int *total, int *avail)
NTSTATUS cli_disk_size(struct cli_state *cli, uint64_t *bsize, uint64_t *total, uint64_t *avail)
{
+ uint64_t sectors_per_block;
+ uint64_t bytes_per_sector;
int old_bsize, old_total, old_avail;
NTSTATUS status;
@@ -4137,6 +4139,49 @@ NTSTATUS cli_disk_size(struct cli_state *cli, uint64_t *bsize, uint64_t *total,
return cli_smb2_dskattr(cli, bsize, total, avail);
}
+ /*
+ * Try the trans2 disk full size info call first.
+ * We already use this in SMBC_fstatvfs_ctx().
+ * Ignore 'actual_available_units' as we only
+ * care about the quota for the caller.
+ */
+
+ status = cli_get_fs_full_size_info(cli,
+ total,
+ avail,
+ NULL,
+ §ors_per_block,
+ &bytes_per_sector);
+
+ /* Try and cope will all varients of "we don't do this call"
+ and fall back to cli_dskattr. */
+
+ if (NT_STATUS_EQUAL(status,NT_STATUS_NOT_IMPLEMENTED) ||
+ NT_STATUS_EQUAL(status,NT_STATUS_NOT_SUPPORTED) ||
+ NT_STATUS_EQUAL(status,NT_STATUS_INVALID_INFO_CLASS) ||
+ NT_STATUS_EQUAL(status,NT_STATUS_PROCEDURE_NOT_FOUND) ||
+ NT_STATUS_EQUAL(status,NT_STATUS_INVALID_LEVEL) ||
+ NT_STATUS_EQUAL(status,NT_STATUS_INVALID_PARAMETER) ||
+ NT_STATUS_EQUAL(status,NT_STATUS_INVALID_DEVICE_REQUEST) ||
+ NT_STATUS_EQUAL(status,NT_STATUS_INVALID_DEVICE_STATE) ||
+ NT_STATUS_EQUAL(status,NT_STATUS_CTL_FILE_NOT_SUPPORTED) ||
+ NT_STATUS_EQUAL(status,NT_STATUS_UNSUCCESSFUL)) {
+ goto try_dskattr;
+ }
+
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ if (bsize) {
+ *bsize = sectors_per_block *
+ bytes_per_sector;
+ }
+
+ return NT_STATUS_OK;
+
+ try_dskattr:
+
/* Old SMB1 core protocol fallback. */
status = cli_dskattr(cli, &old_bsize, &old_total, &old_avail);
if (!NT_STATUS_IS_OK(status)) {
--
2.0.0.526.g5318336
More information about the samba-technical
mailing list