[SCM] Samba Shared Repository - branch master updated

Volker Lendecke vlendec at samba.org
Mon Oct 14 08:49:01 UTC 2024


The branch, master has been updated
       via  1428519372b tests: add test for cli_get_posix_fs_info
       via  6db94eda82c pylibsmb: add python binding for cli_get_posix_fs_info
       via  e2324028f47 smbd: check negotiate before the create context is handled
       via  b8dbf743c13 libsmb: add cli_get_posix_fs_info() for smb2
       via  b9ef0ef134e smbd: add SMB2_FS_POSIX_INFORMATION
       via  3f84d17127d libsmb: make cli_get_posix_fs_info() asynchronous
       via  a4dea49411f smbtorture: Allow debugging output to be configured using smb.conf parameters
      from  9263ce57520 dcesrv_core: better fault codes dcesrv_auth_prepare_auth3()

https://git.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 1428519372bfdee9521d377a399f3cc0d1dd1283
Author: Jule Anger <janger at samba.org>
Date:   Mon Aug 19 11:09:53 2024 +0200

    tests: add test for cli_get_posix_fs_info
    
    Signed-off-by: Jule Anger <janger at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>
    
    Autobuild-User(master): Volker Lendecke <vl at samba.org>
    Autobuild-Date(master): Mon Oct 14 08:48:07 UTC 2024 on atb-devel-224

commit 6db94eda82c9cd954279663d73f9435a2899780f
Author: Jule Anger <janger at samba.org>
Date:   Mon Aug 19 11:03:47 2024 +0200

    pylibsmb: add python binding for cli_get_posix_fs_info
    
    Signed-off-by: Jule Anger <janger at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>

commit e2324028f472a0cdc4467d08bef66f554d99189e
Author: Jule Anger <janger at samba.org>
Date:   Tue Sep 3 14:42:03 2024 +0200

    smbd: check negotiate before the create context is handled
    
    So far, the create context is used as it is sent by the client.
    Now we first check whether posix extensions are negotiated.
    
    Pair-Programmed-With: Ralph Boehme <slow at samba.org>
    Signed-off-by: Jule Anger <janger at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>

commit b8dbf743c1375f47219b73c37e67ce48bd1476cd
Author: Jule Anger <janger at samba.org>
Date:   Tue Sep 3 14:41:40 2024 +0200

    libsmb: add cli_get_posix_fs_info() for smb2
    
    Signed-off-by: Jule Anger <janger at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>

commit b9ef0ef134ea09ba3d8a18c40226b2266cbeb67b
Author: Ralph Boehme <slow at samba.org>
Date:   Wed Jun 26 13:11:18 2024 +0200

    smbd: add SMB2_FS_POSIX_INFORMATION
    
    Needed as in_file_info_class type to query posix filesystem information.
    Used in the subsequent commit.
    
    Pair-Programmed-With: Jule Anger <janger at samba.org>
    Signed-off-by: Jule Anger <janger at samba.org>
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>

commit 3f84d17127d99997bd8ad90ff95a40a1fad663a0
Author: Jule Anger <janger at samba.org>
Date:   Mon Sep 30 15:48:16 2024 +0200

    libsmb: make cli_get_posix_fs_info() asynchronous
    
    Signed-off-by: Jule Anger <janger at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>

commit a4dea49411fc179ce74afc02ab34df4d8cff9bec
Author: Pavel Filipenský <pfilipensky at samba.org>
Date:   Sun Oct 13 21:57:27 2024 +0200

    smbtorture: Allow debugging output to be configured using smb.conf parameters
    
    It might be useful to see timestamps for some smbtorture tests.
    
    Timestamps can be printed via 'debug syslog format=always'.
    It can be specified either in smb.conf or directly via smbtorture option
    -T 'OPTION=VALUE'     smb.conf option line
    
    However, smbtorture is not evaluating the option. It needs to call
    reopen_logs()->debug_set_settings() to copy
    'Globals.debug_syslog_format' to 'state->settings.debug_syslog_format'
    
    $ bin/smbtorture3 //foo/bar -U% LOCAL-G-LOCK4 -d10 -T 'debug syslog format=always'
    
    Before:
    
    dbwrap_lock_order_unlock: release lock order 3 for /home/pfilipen/ws/projects/samba/smbtorture/st/client/lockdir/g_lock.tdb
    waited
    child 2473726 exited with 0
    g_lock_lock_retry: watch_recv returned NT_STATUS_OK
    
    After (see 1 sec delay):
    
    2024-10-13T21:26:56.476859+00:00 addc.addom.samba.example.com smbtorture[2473806]: dbwrap_lock_order_unlock: release lock order 3 for /home/pfilipen/ws/projects/samba/smbtorture/st/client/lockdir/g_lock.tdb
    waited
    child 2473807 exited with 0
    2024-10-13T21:26:57.487363+00:00 addc.addom.samba.example.com smbtorture[2473806]: g_lock_lock_retry: watch_recv returned NT_STATUS_OK
    
    Signed-off-by: Pavel Filipenský <pfilipensky at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>

-----------------------------------------------------------------------

Summary of changes:
 python/samba/tests/smb3unix.py |  20 ++++
 source3/include/trans2.h       |   1 +
 source3/libsmb/cli_smb2_fnum.c | 189 +++++++++++++++++++++++++++++++++++
 source3/libsmb/cli_smb2_fnum.h |  14 +++
 source3/libsmb/clifsinfo.c     | 221 +++++++++++++++++++++++++++++++++++------
 source3/libsmb/proto.h         |  12 +++
 source3/libsmb/pylibsmb.c      |  46 +++++++++
 source3/smbd/open.c            |  90 +++++++++++------
 source3/torture/torture.c      |   2 +
 9 files changed, 531 insertions(+), 64 deletions(-)


Changeset truncated at 500 lines:

diff --git a/python/samba/tests/smb3unix.py b/python/samba/tests/smb3unix.py
index d8e8783670a..302b34776d7 100644
--- a/python/samba/tests/smb3unix.py
+++ b/python/samba/tests/smb3unix.py
@@ -490,3 +490,23 @@ class Smb3UnixTests(samba.tests.libsmb.LibsmbTests):
         l = winconn.list('', mask='test_delete_on_close')
         found_files = {get_string(f['name']): f for f in l}
         self.assertFalse('test_delete_on_close' in found_files)
+
+    def test_posix_fs_info(self):
+        """
+        Test the posix filesystem attributes list given by cli_get_posix_fs_info.
+        With a non-posix connection, a NT_STATUS_INVALID_INFO_CLASS error
+        is expected.
+        """
+        (winconn, posixconn) = self.connections()
+
+        try:
+            posix_info = posixconn.get_posix_fs_info()
+        except Exception as e:
+            self.fail(str(e))
+        self.assertTrue(isinstance(posix_info, dict))
+        self.assertTrue('optimal_transfer_size' in posix_info)
+
+        with self.assertRaises(NTSTATUSError) as cm:
+            winconn.get_posix_fs_info()
+        e = cm.exception
+        self.assertEqual(e.args[0], ntstatus.NT_STATUS_INVALID_INFO_CLASS)
diff --git a/source3/include/trans2.h b/source3/include/trans2.h
index 3ed42a3f0b9..69b60d8a250 100644
--- a/source3/include/trans2.h
+++ b/source3/include/trans2.h
@@ -342,6 +342,7 @@ Byte offset   Type     name                description
 
 /* As yet undefined FSCC_ code for POSIX info level. */
 #define SMB2_FILE_POSIX_INFORMATION			100
+#define SMB2_FS_POSIX_INFORMATION			100
 
 /* MS-FSCC 2.4 File System Information Classes */
 
diff --git a/source3/libsmb/cli_smb2_fnum.c b/source3/libsmb/cli_smb2_fnum.c
index b8c2e9a8acb..91933c6efe9 100644
--- a/source3/libsmb/cli_smb2_fnum.c
+++ b/source3/libsmb/cli_smb2_fnum.c
@@ -45,6 +45,7 @@
 #include "librpc/gen_ndr/ndr_smb3posix.h"
 #include "lib/util/string_wrappers.h"
 #include "lib/util/idtree.h"
+#include "libcli/smb/smb2_posix.h"
 
 struct smb2_hnd {
 	uint64_t fid_persistent;
@@ -4990,3 +4991,191 @@ NTSTATUS cli_smb2_fsctl_recv(
 	tevent_req_received(req);
 	return NT_STATUS_OK;
 }
+
+struct cli_smb2_get_posix_fs_info_state {
+	struct tevent_context *ev;
+	struct cli_state *cli;
+	uint16_t fnum;
+	uint32_t optimal_transfer_size;
+	uint32_t block_size;
+	uint64_t total_blocks;
+	uint64_t blocks_available;
+	uint64_t user_blocks_available;
+	uint64_t total_file_nodes;
+	uint64_t free_file_nodes;
+	uint64_t fs_identifier;
+};
+
+static void cli_smb2_get_posix_fs_info_opened(struct tevent_req *subreq);
+static void cli_smb2_get_posix_fs_info_queried(struct tevent_req *subreq);
+static void cli_smb2_get_posix_fs_info_done(struct tevent_req *subreq);
+
+struct tevent_req *cli_smb2_get_posix_fs_info_send(TALLOC_CTX *mem_ctx,
+						   struct tevent_context *ev,
+						   struct cli_state *cli)
+{
+	struct smb2_create_blobs *cblob = NULL;
+	struct tevent_req *req = NULL, *subreq = NULL;
+	struct cli_smb2_get_posix_fs_info_state *state = NULL;
+	NTSTATUS status;
+
+	req = tevent_req_create(mem_ctx, &state, struct cli_smb2_get_posix_fs_info_state);
+	if (req == NULL) {
+		return NULL;
+	}
+	*state = (struct cli_smb2_get_posix_fs_info_state) {
+		.ev = ev,
+		.cli = cli,
+	};
+	status = make_smb2_posix_create_ctx(state, &cblob, 0);
+	if (!NT_STATUS_IS_OK(status)) {
+		return NULL;
+	}
+
+	/* First open the top level directory. */
+	subreq = cli_smb2_create_fnum_send(state,
+					   state->ev,
+					   state->cli,
+					   "",
+					   (struct cli_smb2_create_flags){0},
+					   SMB2_IMPERSONATION_IMPERSONATION,
+					   FILE_READ_ATTRIBUTES,
+					   FILE_ATTRIBUTE_DIRECTORY,
+					   FILE_SHARE_READ | FILE_SHARE_WRITE |
+						FILE_SHARE_DELETE,
+					   FILE_OPEN,
+					   FILE_DIRECTORY_FILE,
+					   cblob);
+	if (tevent_req_nomem(subreq, req)) {
+		return tevent_req_post(req, ev);
+	}
+
+	tevent_req_set_callback(subreq, cli_smb2_get_posix_fs_info_opened, req);
+	return req;
+}
+
+static void cli_smb2_get_posix_fs_info_opened(struct tevent_req *subreq)
+{
+	struct tevent_req *req = tevent_req_callback_data(
+		subreq, struct tevent_req);
+	struct cli_smb2_get_posix_fs_info_state *state = tevent_req_data(
+		req, struct cli_smb2_get_posix_fs_info_state);
+	struct smb2_create_blobs *cblob = {0};
+	NTSTATUS status;
+
+	status = cli_smb2_create_fnum_recv(subreq,
+					   &state->fnum,
+					   NULL,
+					   state,
+					   cblob,
+					   NULL);
+	TALLOC_FREE(subreq);
+
+	if (tevent_req_nterror(req, status)) {
+		return;
+	}
+
+	subreq = cli_smb2_query_info_fnum_send(
+			state,
+			state->ev,
+			state->cli,
+			state->fnum,
+			SMB2_0_INFO_FILESYSTEM,	   /* in_info_type */
+			SMB2_FS_POSIX_INFORMATION, /* in_file_info_class */
+			0xFFFF,			   /* in_max_output_length */
+			NULL,			   /* in_input_buffer */
+			0,			   /* in_additional_info */
+			0);			   /* in_flags */
+	if (tevent_req_nomem(subreq, req)) {
+		return;
+	}
+
+	tevent_req_set_callback(subreq, cli_smb2_get_posix_fs_info_queried, req);
+}
+
+static void cli_smb2_get_posix_fs_info_queried(struct tevent_req *subreq)
+{
+	struct tevent_req *req = tevent_req_callback_data(
+		subreq, struct tevent_req);
+	struct cli_smb2_get_posix_fs_info_state *state = tevent_req_data(
+		req, struct cli_smb2_get_posix_fs_info_state);
+	DATA_BLOB outbuf = data_blob_null;
+	NTSTATUS status;
+
+	status = cli_smb2_query_info_fnum_recv(subreq, state, &outbuf);
+	TALLOC_FREE(subreq);
+
+	if (tevent_req_nterror(req, status)) {
+		return;
+	}
+
+	 if (outbuf.length != 56) {
+		goto close;
+	 }
+
+	state->optimal_transfer_size = PULL_LE_U32(outbuf.data, 0);
+	state->block_size = PULL_LE_U32(outbuf.data, 4);
+	state->total_blocks = PULL_LE_U64(outbuf.data, 8);
+	state->blocks_available = PULL_LE_U64(outbuf.data, 16);
+	state->user_blocks_available = PULL_LE_U64(outbuf.data, 24);
+	state->total_file_nodes = PULL_LE_U64(outbuf.data, 32);
+	state->free_file_nodes = PULL_LE_U64(outbuf.data, 40);
+	state->fs_identifier = PULL_LE_U64(outbuf.data, 48);
+
+close:
+	subreq = cli_smb2_close_fnum_send(state,
+					  state->ev,
+					  state->cli,
+					  state->fnum,
+					  0);
+	if (tevent_req_nomem(subreq, req)) {
+		return;
+	}
+
+	tevent_req_set_callback(subreq, cli_smb2_get_posix_fs_info_done, req);
+}
+
+static void cli_smb2_get_posix_fs_info_done(struct tevent_req *subreq)
+{
+	struct tevent_req *req = tevent_req_callback_data(
+		subreq, struct tevent_req);
+	NTSTATUS status;
+
+	status = cli_smb2_close_fnum_recv(subreq);
+	TALLOC_FREE(subreq);
+	if (tevent_req_nterror(req, status)) {
+		return;
+	}
+
+	tevent_req_done(req);
+}
+
+NTSTATUS cli_smb2_get_posix_fs_info_recv(struct tevent_req *req,
+					 uint32_t *optimal_transfer_size,
+					 uint32_t *block_size,
+					 uint64_t *total_blocks,
+					 uint64_t *blocks_available,
+					 uint64_t *user_blocks_available,
+					 uint64_t *total_file_nodes,
+					 uint64_t *free_file_nodes,
+					 uint64_t *fs_identifier)
+{
+	struct cli_smb2_get_posix_fs_info_state *state = tevent_req_data(
+		req, struct cli_smb2_get_posix_fs_info_state);
+	NTSTATUS status;
+
+	if (tevent_req_is_nterror(req, &status)) {
+		tevent_req_received(req);
+		return status;
+	}
+	*optimal_transfer_size = state->optimal_transfer_size;
+	*block_size = state->block_size;
+	*total_blocks = state->total_blocks;
+	*blocks_available = state->blocks_available;
+	*user_blocks_available = state->user_blocks_available;
+	*total_file_nodes = state->total_file_nodes;
+	*free_file_nodes = state->free_file_nodes;
+	*fs_identifier = state->fs_identifier;
+	tevent_req_received(req);
+	return NT_STATUS_OK;
+}
diff --git a/source3/libsmb/cli_smb2_fnum.h b/source3/libsmb/cli_smb2_fnum.h
index 2b19e6ebb4e..4399cf31981 100644
--- a/source3/libsmb/cli_smb2_fnum.h
+++ b/source3/libsmb/cli_smb2_fnum.h
@@ -323,4 +323,18 @@ struct tevent_req *cli_smb2_fsctl_send(
 NTSTATUS cli_smb2_fsctl_recv(
 	struct tevent_req *req, TALLOC_CTX *mem_ctx, DATA_BLOB *out);
 
+struct tevent_req *cli_smb2_get_posix_fs_info_send(TALLOC_CTX *mem_ctx,
+						   struct tevent_context *ev,
+						   struct cli_state *cli);
+NTSTATUS cli_smb2_get_posix_fs_info_recv(struct tevent_req *req,
+					 uint32_t *optimal_transfer_size,
+					 uint32_t *block_size,
+					 uint64_t *total_blocks,
+					 uint64_t *blocks_available,
+					 uint64_t *user_blocks_available,
+					 uint64_t *total_file_nodes,
+					 uint64_t *free_file_nodes,
+					 uint64_t *fs_identifier);
+
+
 #endif /* __SMB2CLI_FNUM_H__ */
diff --git a/source3/libsmb/clifsinfo.c b/source3/libsmb/clifsinfo.c
index cc95f47d4b1..4b82a0bd1e9 100644
--- a/source3/libsmb/clifsinfo.c
+++ b/source3/libsmb/clifsinfo.c
@@ -485,64 +485,223 @@ fail:
 	return status;
 }
 
-NTSTATUS cli_get_posix_fs_info(struct cli_state *cli,
-			       uint32_t *optimal_transfer_size,
-			       uint32_t *block_size,
-			       uint64_t *total_blocks,
-			       uint64_t *blocks_available,
-			       uint64_t *user_blocks_available,
-			       uint64_t *total_file_nodes,
-			       uint64_t *free_file_nodes,
-			       uint64_t *fs_identifier)
-{
+struct cli_get_posix_fs_info_state {
 	uint16_t setup[1];
 	uint8_t param[2];
-	uint8_t *rdata = NULL;
-	uint32_t rdata_count;
+	uint32_t optimal_transfer_size;
+	uint32_t block_size;
+	uint64_t total_blocks;
+	uint64_t blocks_available;
+	uint64_t user_blocks_available;
+	uint64_t total_file_nodes;
+	uint64_t free_file_nodes;
+	uint64_t fs_identifier;
+};
+
+static void cli_get_posix_fs_info_done(struct tevent_req *subreq);
+static void cli_get_posix_fs_info_done2(struct tevent_req *subreq);
+
+struct tevent_req *cli_get_posix_fs_info_send(TALLOC_CTX *mem_ctx,
+					      struct tevent_context *ev,
+					      struct cli_state *cli)
+{
+	struct tevent_req *req = NULL, *subreq = NULL;
+	struct cli_get_posix_fs_info_state *state = NULL;
+
+	req = tevent_req_create(mem_ctx, &state,
+				struct cli_get_posix_fs_info_state);
+	if (req == NULL) {
+		return NULL;
+	}
+	SSVAL(state->setup, 0, TRANSACT2_QFSINFO);
+	SSVAL(state->param, 0, SMB_QUERY_POSIX_FS_INFO);
+
+	if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
+		subreq = cli_smb2_get_posix_fs_info_send(mem_ctx, ev, cli);
+		if (tevent_req_nomem(subreq, req)) {
+			return tevent_req_post(req, ev);
+		}
+		tevent_req_set_callback(subreq, cli_get_posix_fs_info_done2, req);
+		return req;
+	}
+
+	subreq = cli_trans_send(talloc_tos(),           /* mem ctx. */
+				ev,                     /* event ctx. */
+				cli,                    /* cli_state. */
+				0,			/* additional_flags2 */
+				SMBtrans2,              /* cmd. */
+				NULL,                   /* pipe name. */
+				0,                      /* fid. */
+				0,                      /* function. */
+				0,                      /* flags. */
+				state->setup,           /* setup. */
+				1,                      /* num setup uint16_t words. */
+				0,                      /* max returned setup. */
+				state->param,           /* param. */
+				2,                      /* num param. */
+				0,                      /* max returned param. */
+				NULL,	                /* data. */
+				0,                      /* num data. */
+				560);                   /* max returned data. */
+
+	if (tevent_req_nomem(subreq, req)) {
+		return tevent_req_post(req, ev);
+	}
+	tevent_req_set_callback(subreq, cli_get_posix_fs_info_done, req);
+	return req;
+}
+
+static void cli_get_posix_fs_info_done(struct tevent_req *subreq)
+{
+	struct tevent_req *req = tevent_req_callback_data(
+		subreq, struct tevent_req);
+	struct cli_get_posix_fs_info_state *state = tevent_req_data(
+		req, struct cli_get_posix_fs_info_state);
+	uint8_t *data = NULL;
+	uint32_t num_data;
 	NTSTATUS status;
 
-	SSVAL(setup, 0, TRANSACT2_QFSINFO);
-	SSVAL(param,0,SMB_QUERY_POSIX_FS_INFO);
+	status = cli_trans_recv(subreq, state, NULL, NULL, 0, NULL,
+				NULL, 0, NULL, &data, 56, &num_data);
+	TALLOC_FREE(subreq);
+	if (tevent_req_nterror(req, status)) {
+		return;
+	}
 
-	status = cli_trans(talloc_tos(), cli, SMBtrans2, NULL, 0, 0, 0,
-			   setup, 1, 0,
-			   param, 2, 0,
-			   NULL, 0, 560,
-			   NULL,
-			   NULL, 0, NULL, /* rsetup */
-			   NULL, 0, NULL, /* rparam */
-			   &rdata, 56, &rdata_count);
-	if (!NT_STATUS_IS_OK(status)) {
+	state->optimal_transfer_size = IVAL(data, 0);
+	state->block_size = IVAL(data,4);
+	state->total_blocks = BIG_UINT(data,8);
+	state->blocks_available = BIG_UINT(data,16);
+	state->user_blocks_available = BIG_UINT(data,24);
+	state->total_file_nodes = BIG_UINT(data,32);
+	state->free_file_nodes = BIG_UINT(data,40);
+	state->fs_identifier = BIG_UINT(data,48);
+	TALLOC_FREE(data);
+	tevent_req_done(req);
+}
+
+static void cli_get_posix_fs_info_done2(struct tevent_req *subreq)
+{
+	struct tevent_req *req = tevent_req_callback_data(
+		subreq, struct tevent_req);
+	struct cli_get_posix_fs_info_state *state = tevent_req_data(
+		req, struct cli_get_posix_fs_info_state);
+	NTSTATUS status;
+	status = cli_smb2_get_posix_fs_info_recv(subreq,
+						 &state->optimal_transfer_size,
+						 &state->block_size,
+						 &state->total_blocks,
+						 &state->blocks_available,
+						 &state->user_blocks_available,
+						 &state->total_file_nodes,
+						 &state->free_file_nodes,
+						 &state->fs_identifier);
+	TALLOC_FREE(subreq);
+	if (tevent_req_nterror(req, status)) {
+		return;
+	}
+
+	tevent_req_done(req);
+}
+
+NTSTATUS cli_get_posix_fs_info_recv(struct tevent_req *req,
+			            uint32_t *optimal_transfer_size,
+			            uint32_t *block_size,
+			            uint64_t *total_blocks,
+			            uint64_t *blocks_available,
+			            uint64_t *user_blocks_available,
+			            uint64_t *total_file_nodes,
+			            uint64_t *free_file_nodes,
+			            uint64_t *fs_identifier)
+{
+	struct cli_get_posix_fs_info_state *state = tevent_req_data(
+			req, struct cli_get_posix_fs_info_state);
+	NTSTATUS status;
+
+	if (tevent_req_is_nterror(req, &status)) {
+		tevent_req_received(req);
 		return status;
 	}
 
 	if (optimal_transfer_size) {
-                *optimal_transfer_size = IVAL(rdata, 0);
+		*optimal_transfer_size = state->optimal_transfer_size;
 	}
 	if (block_size) {
-		*block_size = IVAL(rdata,4);
+		*block_size = state->block_size;
 	}
 	if (total_blocks) {
-		*total_blocks = BIG_UINT(rdata,8);
+		*total_blocks = state->total_blocks;
 	}
 	if (blocks_available) {
-		*blocks_available = BIG_UINT(rdata,16);
+		*blocks_available = state->blocks_available;
 	}
 	if (user_blocks_available) {
-		*user_blocks_available = BIG_UINT(rdata,24);
+		*user_blocks_available = state->user_blocks_available;
 	}
 	if (total_file_nodes) {
-		*total_file_nodes = BIG_UINT(rdata,32);
+		*total_file_nodes = state->total_file_nodes;
 	}
 	if (free_file_nodes) {
-		*free_file_nodes = BIG_UINT(rdata,40);
+		*free_file_nodes = state->free_file_nodes;
 	}
 	if (fs_identifier) {
-		*fs_identifier = BIG_UINT(rdata,48);
+		*fs_identifier = state->fs_identifier;
 	}
+	tevent_req_received(req);
 	return NT_STATUS_OK;
 }
 
+NTSTATUS cli_get_posix_fs_info(struct cli_state *cli,
+			       uint32_t *optimal_transfer_size,
+			       uint32_t *block_size,
+			       uint64_t *total_blocks,
+			       uint64_t *blocks_available,
+			       uint64_t *user_blocks_available,
+			       uint64_t *total_file_nodes,
+			       uint64_t *free_file_nodes,
+			       uint64_t *fs_identifier)
+{
+	TALLOC_CTX *frame = talloc_stackframe();
+	struct tevent_context *ev = NULL;
+	struct tevent_req *req = NULL;
+	NTSTATUS status = NT_STATUS_NO_MEMORY;
+
+	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;
+	}
+
+	ev = samba_tevent_context_init(frame);
+	if (ev == NULL) {
+		goto fail;
+	}
+


-- 
Samba Shared Repository



More information about the samba-cvs mailing list