[SCM] Samba Shared Repository - branch master updated

Noel Power npower at samba.org
Tue Jul 31 17:46:02 UTC 2018


The branch, master has been updated
       via  e053aad s3/utils: fix regression where specifying -Unetbios/root works
       via  705086d s3/smbd: allow set quota for non root user (when built with --enable-selftest)
       via  801c185 s3/script/tests: Add simple (smb1 & smb2) get/set/list tests for smbcquotas
       via  90da2e5 s3/script/test: modify existing smbcquota test to use SMB2 in addition to SMB1.
       via  9070384 s3/smbd: smb2 server implementation for query get/set info.
       via  b8802e2 s3/smbd: adjust smb1 server to use idl structs and generated ndr push/pull funcs
       via  dd21b4f s3/libsmb: adjust smb2 code for new idl structs & generated ndr push/pull funcs.
       via  07e9113 s3/libsmb: adjust smb1 cli code to use idl structs and ndr push/pull funcs.
       via  fd7c6f9 librpc/idl Add some query [getset]info quota related structures
       via  1033dd9 s3/smbd: Don't stat when doing a quota operation (as it's a fake file)
       via  b934082 s3/libsmb: Avoid potential smbpanic calling parse_user_quota_list.
       via  2bfb9b4 s3/lib: Fix misleading typo in debug message
      from  8dac16e smb2_query_directory: make 'return true' explicit in smb2_query_directory_next_entry()

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


- Log -----------------------------------------------------------------
commit e053aad4ae46dfcda6143d55e8e913e923fa34be
Author: Noel Power <noel.power at suse.com>
Date:   Thu Jun 28 16:04:24 2018 +0100

    s3/utils: fix regression where specifying -Unetbios/root works
    
    Usually you need to be root on a linux server to modify quotas. Even
    with a linux server joined to a windows AD you could always log in as
    local root with smbcquotas. However in recent builds this has changed.
    This patch fixes this
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13553
    
    Signed-off-by: Noel Power <noel.power at suse.com>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    
    Autobuild-User(master): Noel Power <npower at samba.org>
    Autobuild-Date(master): Tue Jul 31 19:45:59 CEST 2018 on sn-devel-144

commit 705086d83c847c707e8230ce6a58e840a70d93c3
Author: Noel Power <noel.power at suse.com>
Date:   Wed Mar 22 20:06:13 2017 +0000

    s3/smbd: allow set quota for non root user (when built with --enable-selftest)
    
    Currently it appears you need to be root to set quotas, for test purposes
    this requirement needs to be relaxed.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13553
    
    Signed-off-by: Noel Power <noel.power at suse.com>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 801c1856a39cbc2fd65183a7d6d8b7526dbc251e
Author: Noel Power <noel.power at suse.com>
Date:   Tue Mar 21 08:29:59 2017 +0000

    s3/script/tests: Add simple (smb1 & smb2) get/set/list tests for smbcquotas
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13553
    
    Signed-off-by: Noel Power <noel.power at suse.com>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 90da2e599b1e46beea1d3dc4b6e9338786250882
Author: Noel Power <noel.power at suse.com>
Date:   Wed Mar 8 14:27:27 2017 +0000

    s3/script/test: modify existing smbcquota test to use SMB2 in addition to SMB1.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13553
    
    Signed-off-by: Noel Power <noel.power at suse.com>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 907038417673dc0076838586e620b88513d78cb0
Author: Noel Power <noel.power at suse.com>
Date:   Fri May 26 16:02:33 2017 +0100

    s3/smbd: smb2 server implementation for query get/set info.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13553
    
    Signed-off-by: Noel Power <noel.power at suse.com>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit b8802e271337e5cec4f13ad4f505ae1905e09ca7
Author: Noel Power <noel.power at suse.com>
Date:   Fri May 26 16:01:53 2017 +0100

    s3/smbd: adjust smb1 server to use idl structs and generated ndr push/pull funcs
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13553
    
    Signed-off-by: Noel Power <noel.power at suse.com>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit dd21b4fcfef4a663c43cf8e8601da350cbb0cfd3
Author: Noel Power <noel.power at suse.com>
Date:   Fri May 26 15:50:18 2017 +0100

    s3/libsmb: adjust smb2 code for new idl structs & generated ndr push/pull funcs.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13553
    
    Signed-off-by: Noel Power <noel.power at suse.com>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 07e9113291213831f489aac7cffe3ee99dfb3cea
Author: Noel Power <noel.power at suse.com>
Date:   Fri May 26 15:01:17 2017 +0100

    s3/libsmb: adjust smb1 cli code to use idl structs and ndr push/pull funcs.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13553
    
    Signed-off-by: Noel Power <noel.power at suse.com>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit fd7c6f9bc7eb2de565ae9dc0aae6932904d53ec9
Author: Noel Power <noel.power at suse.com>
Date:   Thu Mar 2 09:20:24 2017 +0000

    librpc/idl Add some query [getset]info quota related structures
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13553
    
    Signed-off-by: Noel Power <noel.power at suse.com>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 1033dd9e303fc91b97e2054713b714ed5f356eb8
Author: Noel Power <noel.power at suse.com>
Date:   Tue Feb 28 11:36:47 2017 +0000

    s3/smbd: Don't stat when doing a quota operation (as it's a fake file)
    
    calling SMB_VFS_STAT on the quota fake file fails and caused
    FS_INFO/FileFsControlInfo request to error out early, in turn stopped a
    Win8.1 client from proceeding with quota queries.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13553
    
    Signed-off-by: Noel Power <noel.power at suse.com>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit b93408246252fe1e3a72de33bcaa8ebb5fe7a1d2
Author: Noel Power <noel.power at suse.com>
Date:   Tue Feb 28 15:04:16 2017 +0000

    s3/libsmb: Avoid potential smbpanic calling parse_user_quota_list.
    
    Calling parse_user_quota_list with a NULL buffer can cause a panic, while
    this shouldn't happen, I managed to trigger this with an early implementation
    of SMB2 quota support in smbd which didn't pass back NT_STATUS_NO_MORE_ENTRIES
    when handling a SMB2_0_INFO_QUOTA GETINFO message.
    OTHOH the Windows client handled the same situation gracefully.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13553
    
    Signed-off-by: Noel Power <noel.power at suse.com>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 2bfb9b4081fff1ef816bbfdd3ebb989d1c56ec1b
Author: Noel Power <noel.power at suse.com>
Date:   Wed Mar 22 14:53:22 2017 +0000

    s3/lib: Fix misleading typo in debug message
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13553
    
    Signed-off-by: Noel Power <noel.power at suse.com>
    Reviewed-by: Jeremy Allison <jra at samba.org>

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

Summary of changes:
 librpc/idl/quota.idl                               |  54 ++
 librpc/idl/wscript_build                           |   1 +
 librpc/wscript_build                               |   5 +
 selftest/target/Samba3.pm                          |   9 +
 source3/lib/sysquotas.c                            |   2 +-
 source3/libsmb/cli_smb2_fnum.c                     |  94 ++-
 source3/libsmb/cliquota.c                          | 392 ++++++------
 source3/libsmb/proto.h                             |   6 +
 source3/script/tests/getset_quota.py               | 154 +++++
 source3/script/tests/test_dfree_quota.sh           |  14 +-
 source3/script/tests/test_smbcquota.py             | 244 ++++++++
 .../script/tests/test_smbcquota.sh                 |  42 +-
 source3/selftest/tests.py                          |   1 +
 source3/smbd/nttrans.c                             | 662 ++++++++++++---------
 source3/smbd/proto.h                               |  14 +
 source3/smbd/smb2_getinfo.c                        |  86 ++-
 source3/smbd/smb2_setinfo.c                        |  36 ++
 source3/smbd/trans2.c                              |   3 +-
 source3/utils/smbcquotas.c                         |   3 +-
 source3/wscript_build                              |   2 +
 20 files changed, 1313 insertions(+), 511 deletions(-)
 create mode 100644 librpc/idl/quota.idl
 create mode 100755 source3/script/tests/getset_quota.py
 create mode 100755 source3/script/tests/test_smbcquota.py
 copy python/samba/tests/policy.py => source3/script/tests/test_smbcquota.sh (52%)
 mode change 100644 => 100755


Changeset truncated at 500 lines:

diff --git a/librpc/idl/quota.idl b/librpc/idl/quota.idl
new file mode 100644
index 0000000..7c4d00a
--- /dev/null
+++ b/librpc/idl/quota.idl
@@ -0,0 +1,54 @@
+#include "idl_types.h"
+
+import "security.idl";
+
+[
+	pointer_default(unique)
+]
+
+interface file_quota {
+
+	/* MS-FSCC 2.4.33.1 */
+	typedef [public] struct {
+		uint32 next_entry_offset;
+		uint32 sid_length;
+		dom_sid sid;
+	} file_get_quota_info;
+
+	/* MS-FSCC 2.4.33 */
+	typedef [public] struct {
+		uint32 next_entry_offset;
+		uint32 sid_length;
+		hyper change_time;
+		hyper quota_used;
+		hyper quota_threshold;
+		hyper quota_limit;
+		dom_sid sid;
+	} file_quota_information;
+}
+
+interface smb2_query_quoata
+{
+	/* MS-SMB2 2.2.37.1 */
+	typedef [public] struct {
+		uint8 return_single;
+		uint8 restart_scan;
+		uint16 reserved;
+		uint32 sid_list_length;
+		uint32 start_sid_length;
+		uint32 start_sid_offset;
+	} smb2_query_quota_info;
+}
+
+interface smb1_nt_transact_query_quota
+{
+	/* MS-SMB 2.2.7.5.1 */
+	typedef [public] struct {
+		uint16 fid;
+		uint8 return_single_entry;
+		uint8 restart_scan;
+		uint32 sid_list_length;
+		uint32 start_sid_length;
+		uint32 start_sid_offset;
+	} nttrans_query_quota_params;
+}
diff --git a/librpc/idl/wscript_build b/librpc/idl/wscript_build
index 75eba7d..f1588cd 100644
--- a/librpc/idl/wscript_build
+++ b/librpc/idl/wscript_build
@@ -38,6 +38,7 @@ bld.SAMBA_PIDL_LIST('PIDL',
                     fsrvp_state.idl
                     cab.idl
                     nfs4acl.idl
+                    quota.idl
                     ''',
                     options='--header --ndr-parser',
                     output_dir='../gen_ndr')
diff --git a/librpc/wscript_build b/librpc/wscript_build
index 36414fb..824c0f9 100644
--- a/librpc/wscript_build
+++ b/librpc/wscript_build
@@ -399,6 +399,11 @@ bld.SAMBA_SUBSYSTEM('NDR_SMB2_LEASE_STRUCT',
     public_headers='gen_ndr/smb2_lease_struct.h'
     )
 
+bld.SAMBA_SUBSYSTEM('NDR_QUOTA',
+    source='gen_ndr/ndr_quota.c',
+    public_deps='ndr',
+    )
+
 bld.SAMBA_SUBSYSTEM('NDR_SCHANNEL',
     source='ndr/ndr_schannel.c gen_ndr/ndr_schannel.c',
     public_deps='ndr ndr_nbt'
diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm
index 5b8cf9e..447c1e8 100755
--- a/selftest/target/Samba3.pm
+++ b/selftest/target/Samba3.pm
@@ -885,6 +885,9 @@ sub setup_fileserver
 	push(@dirs, "$dfree_share_dir/subdir2");
 	push(@dirs, "$dfree_share_dir/subdir3");
 
+	my $quotadir_dir="$share_dir/quota";
+	push(@dirs, $quotadir_dir);
+
 	my $valid_users_sharedir="$share_dir/valid_users";
 	push(@dirs,$valid_users_sharedir);
 
@@ -911,6 +914,8 @@ sub setup_fileserver
 	usershare allow guests = yes
 	usershare prefix allow list = $usershare_sharedir
 
+	get quota command = $prefix_abs/getset_quota.py
+	set quota command = $prefix_abs/getset_quota.py
 [lowercase]
 	path = $lower_case_share_dir
 	comment = smb username is [%U]
@@ -2170,6 +2175,10 @@ sub provision($$$$$$$$$)
 	vfs objects = acl_xattr fake_acls xattr_tdb fake_dfq
 	inherit owner = yes
 	include = $dfqconffile
+[quotadir]
+	path = $shrdir/quota
+	admin users = $unix_name
+
 [acl_xattr_ign_sysacl_posix]
 	copy = tmp
 	acl_xattr:ignore system acls = yes
diff --git a/source3/lib/sysquotas.c b/source3/lib/sysquotas.c
index eef87be..9b2d37b 100644
--- a/source3/lib/sysquotas.c
+++ b/source3/lib/sysquotas.c
@@ -418,7 +418,7 @@ static int command_set_quota(const char *path, enum SMB_QUOTA_TYPE qtype, unid_t
 			return -1;
 		}
 
-		DEBUG (3, ("get_quota: Running command %s\n", syscmd));
+		DBG_NOTICE("set_quota: Running command %s\n", syscmd);
 
 		lines = file_lines_pload(talloc_tos(), syscmd, NULL);
 		SAFE_FREE(syscmd);
diff --git a/source3/libsmb/cli_smb2_fnum.c b/source3/libsmb/cli_smb2_fnum.c
index 4b9871c..3537932 100644
--- a/source3/libsmb/cli_smb2_fnum.c
+++ b/source3/libsmb/cli_smb2_fnum.c
@@ -41,6 +41,7 @@
 #include "lib/util_ea.h"
 #include "librpc/gen_ndr/ndr_ioctl.h"
 #include "ntioctl.h"
+#include "librpc/gen_ndr/ndr_quota.h"
 
 struct smb2_hnd {
 	uint64_t fid_persistent;
@@ -2910,12 +2911,16 @@ NTSTATUS cli_smb2_get_user_quota(struct cli_state *cli,
 {
 	NTSTATUS status;
 	DATA_BLOB inbuf = data_blob_null;
+	DATA_BLOB info_blob = data_blob_null;
 	DATA_BLOB outbuf = data_blob_null;
 	struct smb2_hnd *ph = NULL;
 	TALLOC_CTX *frame = talloc_stackframe();
 	unsigned sid_len;
 	unsigned int offset;
-	uint8_t *buf;
+	struct smb2_query_quota_info query = {0};
+	struct file_get_quota_info info = {0};
+	enum ndr_err_code err;
+	struct ndr_push *ndr_push = NULL;
 
 	if (smbXcli_conn_has_async_calls(cli->conn)) {
 		/*
@@ -2937,27 +2942,52 @@ NTSTATUS cli_smb2_get_user_quota(struct cli_state *cli,
 
 	sid_len = ndr_size_dom_sid(&pqt->sid, 0);
 
-	inbuf = data_blob_talloc_zero(frame, 24 + sid_len);
-	if (inbuf.data == NULL) {
+	query.return_single = 1;
+	if (sid_len < 0) {
+		status = NT_STATUS_INVALID_PARAMETER;
+		goto fail;
+	}
+
+	info.next_entry_offset = 0;
+	info.sid_length = sid_len;
+	info.sid = pqt->sid;
+
+	err = ndr_push_struct_blob(
+			&info_blob,
+			frame,
+			&info,
+			(ndr_push_flags_fn_t)ndr_push_file_get_quota_info);
+
+	if (!NDR_ERR_CODE_IS_SUCCESS(err)) {
+		status = NT_STATUS_INTERNAL_ERROR;
+		goto fail;
+	}
+
+	query.sid_list_length = info_blob.length;
+	ndr_push = ndr_push_init_ctx(frame);
+	if (!ndr_push) {
 		status = NT_STATUS_NO_MEMORY;
 		goto fail;
 	}
 
-	buf = inbuf.data;
+	err = ndr_push_smb2_query_quota_info(ndr_push,
+					     NDR_SCALARS | NDR_BUFFERS,
+					     &query);
 
-	SCVAL(buf, 0, 1);	   /* ReturnSingle */
-	SCVAL(buf, 1, 0);	   /* RestartScan */
-	SSVAL(buf, 2, 0);	   /* Reserved */
-	if (8 + sid_len < 8) {
-		status = NT_STATUS_INVALID_PARAMETER;
+	if (!NDR_ERR_CODE_IS_SUCCESS(err)) {
+		status = NT_STATUS_INTERNAL_ERROR;
+		goto fail;
+	}
+
+	err = ndr_push_array_uint8(ndr_push, NDR_SCALARS, info_blob.data,
+				   info_blob.length);
+
+	if (!NDR_ERR_CODE_IS_SUCCESS(err)) {
+		status = NT_STATUS_INTERNAL_ERROR;
 		goto fail;
 	}
-	SIVAL(buf, 4, 8 + sid_len); /* SidListLength */
-	SIVAL(buf, 8, 0);	   /* StartSidLength */
-	SIVAL(buf, 12, 0);	  /* StartSidOffset */
-	SIVAL(buf, 16, 0);	  /* NextEntryOffset */
-	SIVAL(buf, 20, sid_len);    /* SidLength */
-	sid_linearize(buf + 24, sid_len, &pqt->sid);
+	inbuf.data = ndr_push->data;
+	inbuf.length = ndr_push->offset;
 
 	status = smb2cli_query_info(cli->conn, cli->timeout, cli->smb2.session,
 				    cli->smb2.tcon, 4, /* in_info_type */
@@ -3002,7 +3032,8 @@ NTSTATUS cli_smb2_list_user_quota_step(struct cli_state *cli,
 	DATA_BLOB outbuf = data_blob_null;
 	struct smb2_hnd *ph = NULL;
 	TALLOC_CTX *frame = talloc_stackframe();
-	uint8_t *buf;
+	struct smb2_query_quota_info info = {0};
+	enum ndr_err_code err;
 
 	if (smbXcli_conn_has_async_calls(cli->conn)) {
 		/*
@@ -3022,20 +3053,19 @@ NTSTATUS cli_smb2_list_user_quota_step(struct cli_state *cli,
 		goto cleanup;
 	}
 
-	inbuf = data_blob_talloc_zero(frame, 16);
-	if (inbuf.data == NULL) {
-		status = NT_STATUS_NO_MEMORY;
-		goto cleanup;
-	}
 
-	buf = inbuf.data;
+	info.restart_scan = first ? 1 : 0;
 
-	SCVAL(buf, 0, 0);	     /* ReturnSingle */
-	SCVAL(buf, 1, first ? 1 : 0); /* RestartScan */
-	SSVAL(buf, 2, 0);	     /* Reserved */
-	SIVAL(buf, 4, 0);	     /* SidListLength */
-	SIVAL(buf, 8, 0);	     /* StartSidLength */
-	SIVAL(buf, 12, 0);	    /* StartSidOffset */
+	err = ndr_push_struct_blob(
+			&inbuf,
+			frame,
+			&info,
+			(ndr_push_flags_fn_t)ndr_push_smb2_query_quota_info);
+
+	if (!NDR_ERR_CODE_IS_SUCCESS(err)) {
+		status = NT_STATUS_INTERNAL_ERROR;
+		goto cleanup;
+	}
 
 	status = smb2cli_query_info(cli->conn, cli->timeout, cli->smb2.session,
 				    cli->smb2.tcon, 4, /* in_info_type */
@@ -3047,6 +3077,14 @@ NTSTATUS cli_smb2_list_user_quota_step(struct cli_state *cli,
 				    ph->fid_persistent, ph->fid_volatile, frame,
 				    &outbuf);
 
+	/*
+	 * safeguard against panic from calling parse_user_quota_list with
+	 * NULL buffer
+	 */
+	if (NT_STATUS_IS_OK(status) && outbuf.length == 0) {
+		status = NT_STATUS_NO_MORE_ENTRIES;
+	}
+
 	if (!NT_STATUS_IS_OK(status)) {
 		goto cleanup;
 	}
diff --git a/source3/libsmb/cliquota.c b/source3/libsmb/cliquota.c
index e22ccdd..8efd2bb 100644
--- a/source3/libsmb/cliquota.c
+++ b/source3/libsmb/cliquota.c
@@ -24,6 +24,7 @@
 #include "../libcli/security/security.h"
 #include "trans2.h"
 #include "../libcli/smb/smbXcli_base.h"
+#include "librpc/gen_ndr/ndr_quota.h"
 
 NTSTATUS cli_get_quota_handle(struct cli_state *cli, uint16_t *quota_fnum)
 {
@@ -75,61 +76,39 @@ bool parse_user_quota_record(const uint8_t *rdata,
 			     unsigned int *offset,
 			     SMB_NTQUOTA_STRUCT *pqt)
 {
-	int sid_len;
-	SMB_NTQUOTA_STRUCT qt;
-
-	ZERO_STRUCT(qt);
-
-	if (!rdata||!offset||!pqt) {
-		smb_panic("parse_quota_record: called with NULL POINTER!");
-	}
-
-	if (rdata_count < 40) {
-		return False;
-	}
+	struct file_quota_information info = {0};
+	TALLOC_CTX *frame = talloc_stackframe();
+	DATA_BLOB blob;
+	enum ndr_err_code err;
+	bool result = false;
 
-	/* offset to next quota record.
-	 * 4 bytes IVAL(rdata,0)
-	 * unused here...
-	 */
-	*offset = IVAL(rdata,0);
-
-	/* sid len */
-	sid_len = IVAL(rdata,4);
-	if (40 + sid_len < 40) {
-		return false;
-	}
-
-	if (rdata_count < 40+sid_len) {
-		return False;		
-	}
+	blob.data = discard_const_p(uint8_t, rdata);
+	blob.length = rdata_count;
+	err = ndr_pull_struct_blob(
+			&blob,
+			frame,
+			&info,
+			(ndr_pull_flags_fn_t)ndr_pull_file_quota_information);
 
-	if (*offset != 0 && *offset < 40 + sid_len) {
-		return false;
+	if (!NDR_ERR_CODE_IS_SUCCESS(err)) {
+		goto out;
 	}
 
-	/* unknown 8 bytes in pdata 
-	 * maybe its the change time in NTTIME
-	 */
+	*offset = info.next_entry_offset;
 
-	/* the used space 8 bytes (uint64_t)*/
-	qt.usedspace = BVAL(rdata,16);
+	ZERO_STRUCTP(pqt);
+	pqt->usedspace = info.quota_used;
 
-	/* the soft quotas 8 bytes (uint64_t)*/
-	qt.softlim = BVAL(rdata,24);
+	pqt->softlim = info.quota_threshold;
 
-	/* the hard quotas 8 bytes (uint64_t)*/
-	qt.hardlim = BVAL(rdata,32);
-
-	if (!sid_parse(rdata+40,sid_len,&qt.sid)) {
-		return false;
-	}
+	pqt->hardlim = info.quota_limit;
 
-	qt.qtype = SMB_USER_QUOTA_TYPE;
-
-	*pqt = qt;
-
-	return True;
+	pqt->qtype = SMB_USER_QUOTA_TYPE;
+	pqt->sid = info.sid;
+	result = true;
+out:
+	TALLOC_FREE(frame);
+	return result;
 }
 
 NTSTATUS parse_user_quota_list(const uint8_t *curdata,
@@ -217,111 +196,12 @@ NTSTATUS build_user_quota_buffer(SMB_NTQUOTA_LIST *qt_list,
 				 DATA_BLOB *outbuf,
 				 SMB_NTQUOTA_LIST **end_ptr)
 {
-	uint32_t qt_len = 0;
-	uint8_t *entry;
-	uint32_t entry_len;
-	int sid_len;
-	SMB_NTQUOTA_LIST *qtl;
-	DATA_BLOB qbuf = data_blob_null;
-	NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
-
-	if (qt_list == NULL) {
-		status = NT_STATUS_OK;
-		*outbuf = data_blob_null;
-		if (end_ptr) {
-			*end_ptr = NULL;
-		}
-		return NT_STATUS_OK;
-	}
-
-	for (qtl = qt_list; qtl != NULL; qtl = qtl->next) {
-
-		sid_len = ndr_size_dom_sid(&qtl->quotas->sid, 0);
-		if (47 + sid_len < 47) {
-			status = NT_STATUS_INVALID_PARAMETER;
-			goto fail;
-		}
-		entry_len = 40 + sid_len;
-		entry_len = ((entry_len + 7) / 8) * 8;
-
-		if (qt_len + entry_len < qt_len) {
-			status = NT_STATUS_INVALID_PARAMETER;
-			goto fail;
-		}
-		qt_len += entry_len;
-	}
-
-	if (maxlen > 0 && qt_len > maxlen) {
-		qt_len = maxlen;
-	}
-
-	qbuf = data_blob_talloc_zero(mem_ctx, qt_len);
-	if (qbuf.data == NULL) {
-		status = NT_STATUS_NO_MEMORY;
-		goto fail;
-	}
-
-	for (qt_len = 0, entry = qbuf.data; qt_list != NULL;
-	     qt_list = qt_list->next, qt_len += entry_len, entry += entry_len) {
-
-		sid_len = ndr_size_dom_sid(&qt_list->quotas->sid, 0);
-		entry_len = 40 + sid_len;
-		entry_len = ((entry_len + 7) / 8) * 8;
-
-		if (qt_len + entry_len > qbuf.length) {
-			/* check for not-enough room even for a single
-			 * entry
-			 */
-			if (qt_len == 0) {
-				status = NT_STATUS_BUFFER_TOO_SMALL;
-				goto fail;
-			}
-
-			break;
-		}
-
-		/* nextoffset entry 4 bytes */
-		SIVAL(entry, 0, entry_len);
-
-		/* then the len of the SID 4 bytes */
-		SIVAL(entry, 4, sid_len);
-
-		/* NTTIME of last record change */
-		SBIG_UINT(entry, 8, (uint64_t)0);
-
-		/* the used disk space 8 bytes uint64_t */
-		SBIG_UINT(entry, 16, qt_list->quotas->usedspace);
-
-		/* the soft quotas 8 bytes uint64_t */
-		SBIG_UINT(entry, 24, qt_list->quotas->softlim);
-
-		/* the hard quotas 8 bytes uint64_t */
-		SBIG_UINT(entry, 32, qt_list->quotas->hardlim);
-
-		/* and now the SID */
-		sid_linearize((uint8_t *)(entry + 40), sid_len,
-			      &qt_list->quotas->sid);
-	}
-
-	/* overwrite the offset of the last entry */
-	SIVAL(entry - entry_len, 0, 0);
-
-	/*potentially shrink the buffer if max was given
-	 * and we haven't quite reached the max
-	 */
-	qbuf.length = qt_len;
-	*outbuf = qbuf;
-	qbuf = data_blob_null;
-	status = NT_STATUS_OK;
-
-	if (end_ptr) {
-		*end_ptr = qt_list;
-	}
-
-fail:
-	data_blob_free(&qbuf);
-
-	return status;
+	return fill_quota_buffer(mem_ctx,
+				 qt_list,
+				 false,


-- 
Samba Shared Repository



More information about the samba-cvs mailing list