[PATCH] correct dfree reporting when inherit owner is enabled
Jeremy Allison
jra at samba.org
Fri Aug 12 22:42:18 UTC 2016
On Fri, Aug 12, 2016 at 04:49:02PM +0300, Uri Simchoni wrote:
> Hi,
>
> The following patch set corrects the free disk reporting when "inherit
> owner" is enabled.
>
> In SMB2, the GETINFO_FS query is made relative to a path. That means
> that different results as to disk size and free space can be returned,
> depending on the path.
>
> When "inherit owner" is enabled, new files get the owner of the parent
> directory's owner, and hence consume that owner's quota. Therefore the
> relevant quota for the free disk calculation is the quota of the
> directory owner.
>
> I once submitted this to the list as a new feature with a new parameter,
> but I think this is actually the correct behavior generally, and can be
> filed as a bugfix.
>
> Review appreciated,
> Uri.
Wow. Impressive cleanup - great work Uri ! Reviewed-by: Jeremy Allison <jra at samba.org>.
I'll push as soon as my existing autobuild finishes (or feel free to
push yourself) !
> From f28e0759c90abfdafce555cec916a8b4967d0285 Mon Sep 17 00:00:00 2001
> From: Uri Simchoni <uri at samba.org>
> Date: Wed, 27 Jan 2016 08:12:20 +0200
> Subject: [PATCH 1/5] quotas: small cleanup
>
> Remove an internal function from proto.h
>
> Signed-off-by: Uri Simchoni <uri at samba.org>
> ---
> source3/smbd/proto.h | 1 -
> 1 file changed, 1 deletion(-)
>
> diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h
> index 26fec95..162dbe4 100644
> --- a/source3/smbd/proto.h
> +++ b/source3/smbd/proto.h
> @@ -856,7 +856,6 @@ bool fork_echo_handler(struct smbXsrv_connection *xconn);
>
> bool disk_quotas(connection_struct *conn, const char *path, uint64_t *bsize,
> uint64_t *dfree, uint64_t *dsize);
> -bool disk_quotas_vxfs(const char *name, char *path, uint64_t *bsize, uint64_t *dfree, uint64_t *dsize);
>
> /* The following definitions come from smbd/reply.c */
>
> --
> 2.5.5
>
>
> From a35d00dacbceeb372b9e7132c61dff5c5d5d04a4 Mon Sep 17 00:00:00 2001
> From: Uri Simchoni <uri at samba.org>
> Date: Thu, 14 Jan 2016 00:09:36 +0200
> Subject: [PATCH 2/5] smbd: get a valid file stat to disk_quotas
>
> Most calls to disk_quotas originate at a state with an
> open file descriptor. Pass the file's stat info down to
> disk_quota, so that we can avoid extra stat's and the related
> error handling.
>
> BUG: https://bugzilla.samba.org/show_bug.cgi?id=12145
>
> Signed-off-by: Uri Simchoni <uri at samba.org>
> ---
> source3/modules/vfs_ceph.c | 5 ++---
> source3/modules/vfs_default.c | 5 ++---
> source3/smbd/dfree.c | 16 +++++++---------
> source3/smbd/proto.h | 15 ++++++---------
> source3/smbd/quotas.c | 38 ++++++++++++++++++++------------------
> source3/smbd/reply.c | 13 ++++++++++++-
> source3/smbd/trans2.c | 12 ++++++------
> source3/smbd/vfs.c | 4 ++--
> 8 files changed, 57 insertions(+), 51 deletions(-)
>
> diff --git a/source3/modules/vfs_ceph.c b/source3/modules/vfs_ceph.c
> index 8e11dab..59e9b9c 100644
> --- a/source3/modules/vfs_ceph.c
> +++ b/source3/modules/vfs_ceph.c
> @@ -847,9 +847,8 @@ static int strict_allocate_ftruncate(struct vfs_handle_struct *handle, files_str
> "error %d. Falling back to slow manual allocation\n", errno));
>
> /* available disk space is enough or not? */
> - space_avail = get_dfree_info(fsp->conn,
> - fsp->fsp_name->base_name,
> - &bsize, &dfree, &dsize);
> + space_avail =
> + get_dfree_info(fsp->conn, fsp->fsp_name, &bsize, &dfree, &dsize);
> /* space_avail is 1k blocks */
> if (space_avail == (uint64_t)-1 ||
> ((uint64_t)space_to_write/1024 > space_avail) ) {
> diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c
> index de5a4a3..5227e95 100644
> --- a/source3/modules/vfs_default.c
> +++ b/source3/modules/vfs_default.c
> @@ -1978,9 +1978,8 @@ static int strict_allocate_ftruncate(vfs_handle_struct *handle, files_struct *fs
> "error %d. Falling back to slow manual allocation\n", errno));
>
> /* available disk space is enough or not? */
> - space_avail = get_dfree_info(fsp->conn,
> - fsp->fsp_name->base_name,
> - &bsize, &dfree, &dsize);
> + space_avail =
> + get_dfree_info(fsp->conn, fsp->fsp_name, &bsize, &dfree, &dsize);
> /* space_avail is 1k blocks */
> if (space_avail == (uint64_t)-1 ||
> ((uint64_t)space_to_write/1024 > space_avail) ) {
> diff --git a/source3/smbd/dfree.c b/source3/smbd/dfree.c
> index fc52e51..7e58daa 100644
> --- a/source3/smbd/dfree.c
> +++ b/source3/smbd/dfree.c
> @@ -50,7 +50,7 @@ static void disk_norm(uint64_t *bsize, uint64_t *dfree, uint64_t *dsize)
> Return number of 1K blocks available on a path and total number.
> ****************************************************************************/
>
> -uint64_t sys_disk_free(connection_struct *conn, const char *path,
> +uint64_t sys_disk_free(connection_struct *conn, struct smb_filename *fname,
> uint64_t *bsize, uint64_t *dfree, uint64_t *dsize)
> {
> uint64_t dfree_retval;
> @@ -59,6 +59,7 @@ uint64_t sys_disk_free(connection_struct *conn, const char *path,
> uint64_t dsize_q = 0;
> const char *dfree_command;
> static bool dfree_broken = false;
> + const char *path = fname->base_name;
>
> (*dfree) = (*dsize) = 0;
> (*bsize) = 512;
> @@ -124,7 +125,7 @@ uint64_t sys_disk_free(connection_struct *conn, const char *path,
> return (uint64_t)-1;
> }
>
> - if (disk_quotas(conn, path, &bsize_q, &dfree_q, &dsize_q)) {
> + if (disk_quotas(conn, fname, &bsize_q, &dfree_q, &dsize_q)) {
> uint64_t min_bsize = MIN(*bsize, bsize_q);
>
> (*dfree) = (*dfree) * (*bsize) / min_bsize;
> @@ -168,18 +169,15 @@ dfree_done:
> Potentially returned cached dfree info.
> ****************************************************************************/
>
> -uint64_t get_dfree_info(connection_struct *conn,
> - const char *path,
> - uint64_t *bsize,
> - uint64_t *dfree,
> - uint64_t *dsize)
> +uint64_t get_dfree_info(connection_struct *conn, struct smb_filename *fname,
> + uint64_t *bsize, uint64_t *dfree, uint64_t *dsize)
> {
> int dfree_cache_time = lp_dfree_cache_time(SNUM(conn));
> struct dfree_cached_info *dfc = conn->dfree_info;
> uint64_t dfree_ret;
>
> if (!dfree_cache_time) {
> - return sys_disk_free(conn, path, bsize, dfree, dsize);
> + return sys_disk_free(conn, fname, bsize, dfree, dsize);
> }
>
> if (dfc && (conn->lastused - dfc->last_dfree_time < dfree_cache_time)) {
> @@ -190,7 +188,7 @@ uint64_t get_dfree_info(connection_struct *conn,
> return dfc->dfree_ret;
> }
>
> - dfree_ret = sys_disk_free(conn, path, bsize, dfree, dsize);
> + dfree_ret = sys_disk_free(conn, fname, bsize, dfree, dsize);
>
> if (dfree_ret == (uint64_t)-1) {
> /* Don't cache bad data. */
> diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h
> index 162dbe4..e591910 100644
> --- a/source3/smbd/proto.h
> +++ b/source3/smbd/proto.h
> @@ -172,13 +172,10 @@ bool connections_snum_used(struct smbd_server_connection *unused, int snum);
>
> /* The following definitions come from smbd/dfree.c */
>
> -uint64_t sys_disk_free(connection_struct *conn, const char *path,
> - uint64_t *bsize,uint64_t *dfree,uint64_t *dsize);
> -uint64_t get_dfree_info(connection_struct *conn,
> - const char *path,
> - uint64_t *bsize,
> - uint64_t *dfree,
> - uint64_t *dsize);
> +uint64_t sys_disk_free(connection_struct *conn, struct smb_filename *fname,
> + uint64_t *bsize, uint64_t *dfree, uint64_t *dsize);
> +uint64_t get_dfree_info(connection_struct *conn, struct smb_filename *fname,
> + uint64_t *bsize, uint64_t *dfree, uint64_t *dsize);
>
> /* The following definitions come from smbd/dir.c */
>
> @@ -854,8 +851,8 @@ bool fork_echo_handler(struct smbXsrv_connection *xconn);
>
> /* The following definitions come from smbd/quotas.c */
>
> -bool disk_quotas(connection_struct *conn, const char *path, uint64_t *bsize,
> - uint64_t *dfree, uint64_t *dsize);
> +bool disk_quotas(connection_struct *conn, struct smb_filename *fname,
> + uint64_t *bsize, uint64_t *dfree, uint64_t *dsize);
>
> /* The following definitions come from smbd/reply.c */
>
> diff --git a/source3/smbd/quotas.c b/source3/smbd/quotas.c
> index 9d3b906..f3a727c 100644
> --- a/source3/smbd/quotas.c
> +++ b/source3/smbd/quotas.c
> @@ -216,8 +216,8 @@ try to get the disk space from disk quotas (SunOS & Solaris2 version)
> Quota code by Peter Urbanec (amiga at cse.unsw.edu.au).
> ****************************************************************************/
>
> -bool disk_quotas(connection_struct *conn, const char *path, uint64_t *bsize,
> - uint64_t *dfree, uint64_t *dsize)
> +bool disk_quotas(connection_struct *conn, struct smb_filename *fname,
> + uint64_t *bsize, uint64_t *dfree, uint64_t *dsize)
> {
> uid_t euser_id;
> int ret;
> @@ -230,14 +230,11 @@ bool disk_quotas(connection_struct *conn, const char *path, uint64_t *bsize,
> SMB_STRUCT_STAT sbuf;
> SMB_DEV_T devno;
> bool found = false;
> + const char *path = fname->base_name;
>
> euser_id = geteuid();
>
> - if (sys_stat(path, &sbuf, false) == -1) {
> - return false;
> - }
> -
> - devno = sbuf.st_ex_dev ;
> + devno = fname->st.st_ex_dev;
> DEBUG(5,("disk_quotas: looking for path \"%s\" devno=%x\n",
> path, (unsigned int)devno));
> if ((fd = fopen(MNTTAB, "r")) == NULL) {
> @@ -362,15 +359,16 @@ bool disk_quotas(connection_struct *conn, const char *path, uint64_t *bsize,
> try to get the disk space from disk quotas - default version
> ****************************************************************************/
>
> -bool disk_quotas(connection_struct *conn, const char *path, uint64_t *bsize,
> - uint64_t *dfree, uint64_t *dsize)
> +bool disk_quotas(connection_struct *conn, struct smb_filename *fname,
> + uint64_t *bsize, uint64_t *dfree, uint64_t *dsize)
> {
> int r;
> struct dqblk D;
> uid_t euser_id;
> + const char *path = fname->base_name;
> #if !defined(AIX)
> char dev_disk[256];
> - SMB_STRUCT_STAT S;
> + SMB_STRUCT_STAT S = fname->st;
>
> /* find the block device file */
>
> @@ -463,8 +461,8 @@ bool disk_quotas(connection_struct *conn, const char *path, uint64_t *bsize,
>
> #else /* WITH_QUOTAS */
>
> -bool disk_quotas(connection_struct *conn, const char *path, uint64_t *bsize,
> - uint64_t *dfree, uint64_t *dsize)
> +bool disk_quotas(connection_struct *conn, struct smb_filename *fname,
> + uint64_t *bsize, uint64_t *dfree, uint64_t *dsize)
> {
> (*bsize) = 512; /* This value should be ignored */
>
> @@ -482,8 +480,8 @@ bool disk_quotas(connection_struct *conn, const char *path, uint64_t *bsize,
> /* wrapper to the new sys_quota interface
> this file should be removed later
> */
> -bool disk_quotas(connection_struct *conn, const char *path, uint64_t *bsize,
> - uint64_t *dfree, uint64_t *dsize)
> +bool disk_quotas(connection_struct *conn, struct smb_filename *fname,
> + uint64_t *bsize, uint64_t *dfree, uint64_t *dsize)
> {
> int r;
> SMB_DISK_QUOTA D;
> @@ -496,7 +494,8 @@ bool disk_quotas(connection_struct *conn, const char *path, uint64_t *bsize,
> */
> ZERO_STRUCT(D);
> id.uid = -1;
> - r = SMB_VFS_GET_QUOTA(conn, path, SMB_USER_FS_QUOTA_TYPE, id, &D);
> + r = SMB_VFS_GET_QUOTA(conn, fname->base_name, SMB_USER_FS_QUOTA_TYPE,
> + id, &D);
> if (r == -1 && errno != ENOSYS) {
> goto try_group_quota;
> }
> @@ -507,7 +506,8 @@ bool disk_quotas(connection_struct *conn, const char *path, uint64_t *bsize,
> ZERO_STRUCT(D);
> id.uid = geteuid();
>
> - r = SMB_VFS_GET_QUOTA(conn, path, SMB_USER_QUOTA_TYPE, id, &D);
> + r = SMB_VFS_GET_QUOTA(conn, fname->base_name, SMB_USER_QUOTA_TYPE, id,
> + &D);
>
> if (r == -1) {
> goto try_group_quota;
> @@ -543,7 +543,8 @@ try_group_quota:
> */
> ZERO_STRUCT(D);
> id.gid = -1;
> - r = SMB_VFS_GET_QUOTA(conn, path, SMB_GROUP_FS_QUOTA_TYPE, id, &D);
> + r = SMB_VFS_GET_QUOTA(conn, fname->base_name, SMB_GROUP_FS_QUOTA_TYPE,
> + id, &D);
> if (r == -1 && errno != ENOSYS) {
> return false;
> }
> @@ -554,7 +555,8 @@ try_group_quota:
> id.gid = getegid();
>
> ZERO_STRUCT(D);
> - r = SMB_VFS_GET_QUOTA(conn, path, SMB_GROUP_QUOTA_TYPE, id, &D);
> + r = SMB_VFS_GET_QUOTA(conn, fname->base_name, SMB_GROUP_QUOTA_TYPE, id,
> + &D);
>
> if (r == -1) {
> return False;
> diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
> index 0b7a4fb..4f1ecb1 100644
> --- a/source3/smbd/reply.c
> +++ b/source3/smbd/reply.c
> @@ -1573,9 +1573,20 @@ void reply_dskattr(struct smb_request *req)
> connection_struct *conn = req->conn;
> uint64_t ret;
> uint64_t dfree,dsize,bsize;
> + struct smb_filename smb_fname;
> START_PROFILE(SMBdskattr);
>
> - ret = get_dfree_info(conn, ".", &bsize, &dfree, &dsize);
> + ZERO_STRUCT(smb_fname);
> + smb_fname.base_name = discard_const_p(char, ".");
> +
> + if (SMB_VFS_STAT(conn, &smb_fname) != 0) {
> + reply_nterror(req, map_nt_error_from_unix(errno));
> + DBG_WARNING("stat of . failed (%s)\n", strerror(errno));
> + END_PROFILE(SMBdskattr);
> + return;
> + }
> +
> + ret = get_dfree_info(conn, &smb_fname, &bsize, &dfree, &dsize);
> if (ret == (uint64_t)-1) {
> reply_nterror(req, map_nt_error_from_unix(errno));
> END_PROFILE(SMBdskattr);
> diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
> index 9c0660b..1775316 100644
> --- a/source3/smbd/trans2.c
> +++ b/source3/smbd/trans2.c
> @@ -3438,8 +3438,8 @@ NTSTATUS smbd_do_qfsinfo(struct smbXsrv_connection *xconn,
> {
> uint64_t dfree,dsize,bsize,block_size,sectors_per_unit;
> data_len = 18;
> - df_ret = get_dfree_info(conn, filename, &bsize, &dfree,
> - &dsize);
> + df_ret = get_dfree_info(conn, &smb_fname, &bsize,
> + &dfree, &dsize);
> if (df_ret == (uint64_t)-1) {
> return map_nt_error_from_unix(errno);
> }
> @@ -3589,8 +3589,8 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_ex_dev, (u
> {
> uint64_t dfree,dsize,bsize,block_size,sectors_per_unit;
> data_len = 24;
> - df_ret = get_dfree_info(conn, filename, &bsize, &dfree,
> - &dsize);
> + df_ret = get_dfree_info(conn, &smb_fname, &bsize,
> + &dfree, &dsize);
> if (df_ret == (uint64_t)-1) {
> return map_nt_error_from_unix(errno);
> }
> @@ -3623,8 +3623,8 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned
> {
> uint64_t dfree,dsize,bsize,block_size,sectors_per_unit;
> data_len = 32;
> - df_ret = get_dfree_info(conn, filename, &bsize, &dfree,
> - &dsize);
> + df_ret = get_dfree_info(conn, &smb_fname, &bsize,
> + &dfree, &dsize);
> if (df_ret == (uint64_t)-1) {
> return map_nt_error_from_unix(errno);
> }
> diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c
> index 605f9ad..45562ee 100644
> --- a/source3/smbd/vfs.c
> +++ b/source3/smbd/vfs.c
> @@ -623,8 +623,8 @@ int vfs_allocate_file_space(files_struct *fsp, uint64_t len)
>
> len -= fsp->fsp_name->st.st_ex_size;
> len /= 1024; /* Len is now number of 1k blocks needed. */
> - space_avail = get_dfree_info(conn, fsp->fsp_name->base_name,
> - &bsize, &dfree, &dsize);
> + space_avail =
> + get_dfree_info(conn, fsp->fsp_name, &bsize, &dfree, &dsize);
> if (space_avail == (uint64_t)-1) {
> return -1;
> }
> --
> 2.5.5
>
>
> From 7c40ccde4856b9599aca38972eb1fcd6fd8ae6ff Mon Sep 17 00:00:00 2001
> From: Uri Simchoni <uri at samba.org>
> Date: Thu, 11 Aug 2016 23:37:42 +0300
> Subject: [PATCH 3/5] smbd: use owner uid for free disk calculation if owner is
> inherited
>
> If "inherit owner" is enabled, then new files created under a
> directory shall consume the quota of the directory's owner, so
> the free disk calculation should take that quota into account,
> not the quota of the user creating the file.
>
> BUG: https://bugzilla.samba.org/show_bug.cgi?id=12145
>
> Signed-off-by: Uri Simchoni <uri at samba.org>
> ---
> source3/smbd/quotas.c | 21 +++++++++++++++++++--
> 1 file changed, 19 insertions(+), 2 deletions(-)
>
> diff --git a/source3/smbd/quotas.c b/source3/smbd/quotas.c
> index f3a727c..2db18cd 100644
> --- a/source3/smbd/quotas.c
> +++ b/source3/smbd/quotas.c
> @@ -506,8 +506,25 @@ bool disk_quotas(connection_struct *conn, struct smb_filename *fname,
> ZERO_STRUCT(D);
> id.uid = geteuid();
>
> - r = SMB_VFS_GET_QUOTA(conn, fname->base_name, SMB_USER_QUOTA_TYPE, id,
> - &D);
> + /* if new files created under this folder get this
> + * folder's UID, then available space is governed by
> + * the quota of the folder's UID, not the creating user.
> + */
> + if (lp_inherit_owner(SNUM(conn)) != INHERIT_OWNER_NO &&
> + id.uid != fname->st.st_ex_uid && id.uid != sec_initial_uid()) {
> + int save_errno;
> +
> + id.uid = fname->st.st_ex_uid;
> + become_root();
> + r = SMB_VFS_GET_QUOTA(conn, fname->base_name,
> + SMB_USER_QUOTA_TYPE, id, &D);
> + save_errno = errno;
> + unbecome_root();
> + errno = save_errno;
> + } else {
> + r = SMB_VFS_GET_QUOTA(conn, fname->base_name,
> + SMB_USER_QUOTA_TYPE, id, &D);
> + }
>
> if (r == -1) {
> goto try_group_quota;
> --
> 2.5.5
>
>
> From 9a8e93d0f1c9768477cb67747e7e6b738b8c33e5 Mon Sep 17 00:00:00 2001
> From: Uri Simchoni <uri at samba.org>
> Date: Wed, 20 Jan 2016 21:54:24 +0200
> Subject: [PATCH 4/5] selftest: refactor test_dfree_quota.sh - add share
> parameter
>
> Add a share parameter to individual disk-free tests. This will
> allow running tests on shares other than dfq share.
>
> BUG: https://bugzilla.samba.org/show_bug.cgi?id=12145
>
> Signed-off-by: Uri Simchoni <uri at samba.org>
> ---
> source3/script/tests/test_dfree_quota.sh | 47 ++++++++++++++++----------------
> 1 file changed, 24 insertions(+), 23 deletions(-)
>
> diff --git a/source3/script/tests/test_dfree_quota.sh b/source3/script/tests/test_dfree_quota.sh
> index ab28a07..79b8d7c 100755
> --- a/source3/script/tests/test_dfree_quota.sh
> +++ b/source3/script/tests/test_dfree_quota.sh
> @@ -99,16 +99,17 @@ setup_conf() {
>
> test_smbclient_dfree() {
> name="$1"
> - dir="$2"
> - confs="$3"
> - expected="$4"
> - shift
> + share="$2"
> + dir="$3"
> + confs="$4"
> + expected="$5"
> + shift
> shift
> shift
> shift
> subunit_start_test "$name"
> setup_conf $confs
> - output=$($VALGRIND $smbclient //$SERVER/dfq -c "cd $dir; l" $@ 2>&1)
> + output=$($VALGRIND $smbclient //$SERVER/$share -c "cd $dir; l" $@ 2>&1)
> status=$?
> if [ "$status" = "0" ]; then
> received=$(echo "$output" | awk '/blocks of size/ {print $1, $5, $6}')
> @@ -150,39 +151,39 @@ test_smbcquotas() {
> }
>
> #basic disk-free tests
> -test_smbclient_dfree "Test dfree share root SMB3 no quota" "." "conf1 ." "10 1024. 5" -U$USERNAME%$PASSWORD --option=clientmaxprotocol=SMB3 || failed=`expr $failed + 1`
> -test_smbclient_dfree "Test dfree subdir SMB3 no quota" "subdir1" "conf1 . conf2 subdir1" "20 1024. 10" -U$USERNAME%$PASSWORD --option=clientmaxprotocol=SMB3 || failed=`expr $failed + 1`
> -test_smbclient_dfree "Test dfree subdir NT1 no quota" "subdir1" "conf1 . conf2 subdir1" "10 1024. 5" -U$USERNAME%$PASSWORD --option=clientmaxprotocol=NT1 || failed=`expr $failed + 1`
> -test_smbclient_dfree "Test large disk" "." "conf3 ." "1125899906842624 1024. 3000" -U$USERNAME%$PASSWORD --option=clientmaxprotocol=SMB3 || failed=`expr $failed + 1`
> +test_smbclient_dfree "Test dfree share root SMB3 no quota" dfq "." "conf1 ." "10 1024. 5" -U$USERNAME%$PASSWORD --option=clientmaxprotocol=SMB3 || failed=`expr $failed + 1`
> +test_smbclient_dfree "Test dfree subdir SMB3 no quota" dfq "subdir1" "conf1 . conf2 subdir1" "20 1024. 10" -U$USERNAME%$PASSWORD --option=clientmaxprotocol=SMB3 || failed=`expr $failed + 1`
> +test_smbclient_dfree "Test dfree subdir NT1 no quota" dfq "subdir1" "conf1 . conf2 subdir1" "10 1024. 5" -U$USERNAME%$PASSWORD --option=clientmaxprotocol=NT1 || failed=`expr $failed + 1`
> +test_smbclient_dfree "Test large disk" dfq "." "conf3 ." "1125899906842624 1024. 3000" -U$USERNAME%$PASSWORD --option=clientmaxprotocol=SMB3 || failed=`expr $failed + 1`
> #basic quota test (SMB1 only)
> test_smbcquotas "Test user quota" confq1 $USERNAME "40960/4096000/3072000" -U$USERNAME%$PASSWORD --option=clientmaxprotocol=NT1 || failed=`expr $failed + 1`
>
> #quota limit > disk size, remaining quota > disk free
> -test_smbclient_dfree "Test dfree share root df vs quota case 1" "." "confdfq1 ." "80 1024. 40" -U$USERNAME%$PASSWORD --option=clientmaxprotocol=SMB3 || failed=`expr $failed + 1`
> +test_smbclient_dfree "Test dfree share root df vs quota case 1" dfq "." "confdfq1 ." "80 1024. 40" -U$USERNAME%$PASSWORD --option=clientmaxprotocol=SMB3 || failed=`expr $failed + 1`
> #quota limit > disk size, remaining quota < disk free
> -test_smbclient_dfree "Test dfree share root df vs quota case 2" "." "confdfq2 ." "80 1024. 12" -U$USERNAME%$PASSWORD --option=clientmaxprotocol=SMB3 || failed=`expr $failed + 1`
> +test_smbclient_dfree "Test dfree share root df vs quota case 2" dfq "." "confdfq2 ." "80 1024. 12" -U$USERNAME%$PASSWORD --option=clientmaxprotocol=SMB3 || failed=`expr $failed + 1`
> #quota limit < disk size, remaining quota > disk free
> -test_smbclient_dfree "Test dfree share root df vs quota case 3" "." "confdfq3 ." "160 1024. 40" -U$USERNAME%$PASSWORD --option=clientmaxprotocol=SMB3 || failed=`expr $failed + 1`
> +test_smbclient_dfree "Test dfree share root df vs quota case 3" dfq "." "confdfq3 ." "160 1024. 40" -U$USERNAME%$PASSWORD --option=clientmaxprotocol=SMB3 || failed=`expr $failed + 1`
> #quota limit < disk size, remaining quota < disk free
> -test_smbclient_dfree "Test dfree share root df vs quota case 4" "." "confdfq4 ." "160 1024. 12" -U$USERNAME%$PASSWORD --option=clientmaxprotocol=SMB3 || failed=`expr $failed + 1`
> -test_smbclient_dfree "Test dfree subdir df vs quota case 4" "subdir1" "confdfq4 subdir1" "160 1024. 12" -U$USERNAME%$PASSWORD --option=clientmaxprotocol=SMB3 || failed=`expr $failed + 1`
> +test_smbclient_dfree "Test dfree share root df vs quota case 4" dfq "." "confdfq4 ." "160 1024. 12" -U$USERNAME%$PASSWORD --option=clientmaxprotocol=SMB3 || failed=`expr $failed + 1`
> +test_smbclient_dfree "Test dfree subdir df vs quota case 4" dfq "subdir1" "confdfq4 subdir1" "160 1024. 12" -U$USERNAME%$PASSWORD --option=clientmaxprotocol=SMB3 || failed=`expr $failed + 1`
>
> #quota-->disk free special cases
> -test_smbclient_dfree "Test quota->dfree soft limit" "subdir1" "slimit subdir1" "168 1024. 0" -U$USERNAME%$PASSWORD --option=clientmaxprotocol=SMB3 || failed=`expr $failed + 1`
> -test_smbclient_dfree "Test quota->dfree hard limit" "subdir1" "hlimit subdir1" "180 1024. 0" -U$USERNAME%$PASSWORD --option=clientmaxprotocol=SMB3 || failed=`expr $failed + 1`
> -test_smbclient_dfree "Test quota->dfree inode soft limit" "subdir1" "islimit subdir1" "148 1024. 0" -U$USERNAME%$PASSWORD --option=clientmaxprotocol=SMB3 || failed=`expr $failed + 1`
> -test_smbclient_dfree "Test quota->dfree inode hard limit" "subdir1" "ihlimit subdir1" "148 1024. 0" -U$USERNAME%$PASSWORD --option=clientmaxprotocol=SMB3 || failed=`expr $failed + 1`
> -test_smbclient_dfree "Test quota->dfree err try group" "subdir1" "trygrp1 subdir1" "240 1024. 20" -U$USERNAME%$PASSWORD --option=clientmaxprotocol=SMB3 || failed=`expr $failed + 1`
> -test_smbclient_dfree "Test quota->dfree no-quota try group" "subdir1" "trygrp2 subdir1" "240 1024. 16" -U$USERNAME%$PASSWORD --option=clientmaxprotocol=SMB3 || failed=`expr $failed + 1`
> +test_smbclient_dfree "Test quota->dfree soft limit" dfq "subdir1" "slimit subdir1" "168 1024. 0" -U$USERNAME%$PASSWORD --option=clientmaxprotocol=SMB3 || failed=`expr $failed + 1`
> +test_smbclient_dfree "Test quota->dfree hard limit" dfq "subdir1" "hlimit subdir1" "180 1024. 0" -U$USERNAME%$PASSWORD --option=clientmaxprotocol=SMB3 || failed=`expr $failed + 1`
> +test_smbclient_dfree "Test quota->dfree inode soft limit" dfq "subdir1" "islimit subdir1" "148 1024. 0" -U$USERNAME%$PASSWORD --option=clientmaxprotocol=SMB3 || failed=`expr $failed + 1`
> +test_smbclient_dfree "Test quota->dfree inode hard limit" dfq "subdir1" "ihlimit subdir1" "148 1024. 0" -U$USERNAME%$PASSWORD --option=clientmaxprotocol=SMB3 || failed=`expr $failed + 1`
> +test_smbclient_dfree "Test quota->dfree err try group" dfq "subdir1" "trygrp1 subdir1" "240 1024. 20" -U$USERNAME%$PASSWORD --option=clientmaxprotocol=SMB3 || failed=`expr $failed + 1`
> +test_smbclient_dfree "Test quota->dfree no-quota try group" dfq "subdir1" "trygrp2 subdir1" "240 1024. 16" -U$USERNAME%$PASSWORD --option=clientmaxprotocol=SMB3 || failed=`expr $failed + 1`
>
> #block size different in quota and df systems
> -test_smbclient_dfree "Test quota->dfree different block size" "subdir1" "blksize subdir1" "307200 1024. 307200" -U$USERNAME%$PASSWORD --option=clientmaxprotocol=SMB3 || failed=`expr $failed + 1`
> +test_smbclient_dfree "Test quota->dfree different block size" dfq "subdir1" "blksize subdir1" "307200 1024. 307200" -U$USERNAME%$PASSWORD --option=clientmaxprotocol=SMB3 || failed=`expr $failed + 1`
>
> #quota configured but not enforced
> -test_smbclient_dfree "Test dfree share root quota not enforced" "." "notenforce ." "320 1024. 40" -U$USERNAME%$PASSWORD --option=clientmaxprotocol=SMB3 || failed=`expr $failed + 1`
> +test_smbclient_dfree "Test dfree share root quota not enforced" dfq "." "notenforce ." "320 1024. 40" -U$USERNAME%$PASSWORD --option=clientmaxprotocol=SMB3 || failed=`expr $failed + 1`
>
> #FS quota not implemented (NFS case)
> -test_smbclient_dfree "Test dfree share root FS quota not implemented" "." "nfs ." "160 1024. 12" -U$USERNAME%$PASSWORD --option=clientmaxprotocol=SMB3 || failed=`expr $failed + 1`
> +test_smbclient_dfree "Test dfree share root FS quota not implemented" dfq "." "nfs ." "160 1024. 12" -U$USERNAME%$PASSWORD --option=clientmaxprotocol=SMB3 || failed=`expr $failed + 1`
>
> setup_conf
> exit $failed
> --
> 2.5.5
>
>
> From bb38d0488c940aa966ed5bf7ccc6c16a974b9c06 Mon Sep 17 00:00:00 2001
> From: Uri Simchoni <uri at samba.org>
> Date: Thu, 11 Aug 2016 23:54:22 +0300
> Subject: [PATCH 5/5] selftest: add tests for dfree with inherit owner enabled
>
> BUG: https://bugzilla.samba.org/show_bug.cgi?id=12145
>
> Signed-off-by: Uri Simchoni <uri at samba.org>
> ---
> selftest/target/Samba3.pm | 21 +++++++++++++++---
> source3/script/tests/test_dfree_quota.sh | 37 ++++++++++++++++++++++++++++++--
> source3/selftest/tests.py | 2 +-
> 3 files changed, 54 insertions(+), 6 deletions(-)
>
> diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm
> index a0996a8..8fc3204 100755
> --- a/selftest/target/Samba3.pm
> +++ b/selftest/target/Samba3.pm
> @@ -614,6 +614,7 @@ sub setup_fileserver($$)
> push(@dirs, $dfree_share_dir);
> push(@dirs, "$dfree_share_dir/subdir1");
> push(@dirs, "$dfree_share_dir/subdir2");
> + push(@dirs, "$dfree_share_dir/subdir3");
>
> my $valid_users_sharedir="$share_dir/valid_users";
> push(@dirs,$valid_users_sharedir);
> @@ -1114,7 +1115,6 @@ sub createuser($$$$)
> warn("Unable to set password for $username account\n$cmd");
> return undef;
> }
> - print "DONE\n";
> }
>
> sub provision($$$$$$$$)
> @@ -1344,8 +1344,10 @@ sub provision($$$$$$$$)
> my ($gid_nobody, $gid_nogroup, $gid_root, $gid_domusers, $gid_domadmins);
> my ($gid_userdup, $gid_everyone);
> my ($gid_force_user);
> + my ($uid_user1);
> + my ($uid_user2);
>
> - if ($unix_uid < 0xffff - 7) {
> + if ($unix_uid < 0xffff - 10) {
> $max_uid = 0xffff;
> } else {
> $max_uid = $unix_uid;
> @@ -1359,6 +1361,8 @@ sub provision($$$$$$$$)
> $uid_pdbtest_wkn = $max_uid - 6;
> $uid_force_user = $max_uid - 7;
> $uid_smbget = $max_uid - 8;
> + $uid_user1 = $max_uid - 9;
> + $uid_user2 = $max_uid - 10;
>
> if ($unix_gids[0] < 0xffff - 8) {
> $max_gid = 0xffff;
> @@ -1780,9 +1784,14 @@ sub provision($$$$$$$$)
> wide links = yes
> [dfq]
> path = $shrdir/dfree
> - vfs objects = fake_dfq
> + vfs objects = acl_xattr fake_acls xattr_tdb fake_dfq
> admin users = $unix_name
> include = $dfqconffile
> +[dfq_owner]
> + path = $shrdir/dfree
> + vfs objects = acl_xattr fake_acls xattr_tdb fake_dfq
> + inherit owner = yes
> + include = $dfqconffile
> ";
> close(CONF);
>
> @@ -1808,6 +1817,8 @@ userdup:x:$uid_userdup:$gid_userdup:userdup gecos:$prefix_abs:/bin/false
> pdbtest_wkn:x:$uid_pdbtest_wkn:$gid_everyone:pdbtest_wkn gecos:$prefix_abs:/bin/false
> force_user:x:$uid_force_user:$gid_force_user:force user gecos:$prefix_abs:/bin/false
> smbget_user:x:$uid_smbget:$gid_domusers:smbget_user gecos:$prefix_abs:/bin/false
> +user1:x:$uid_user1:$gid_nogroup:user1 gecos:$prefix_abs:/bin/false
> +user2:x:$uid_user2:$gid_nogroup:user2 gecos:$prefix_abs:/bin/false
> ";
> if ($unix_uid != 0) {
> print PASSWD "root:x:$uid_root:$gid_root:root gecos:$prefix_abs:/bin/false
> @@ -1882,12 +1893,16 @@ force_user:x:$gid_force_user:
> createuser($self, $unix_name, $password, $conffile) || die("Unable to create user");
> createuser($self, "force_user", $password, $conffile) || die("Unable to create force_user");
> createuser($self, "smbget_user", $password, $conffile) || die("Unable to create smbget_user");
> + createuser($self, "user1", $password, $conffile) || die("Unable to create user1");
> + createuser($self, "user2", $password, $conffile) || die("Unable to create user2");
>
> open(DNS_UPDATE_LIST, ">$prefix/dns_update_list") or die("Unable to open $$prefix/dns_update_list");
> print DNS_UPDATE_LIST "A $server. $server_ip\n";
> print DNS_UPDATE_LIST "AAAA $server. $server_ipv6\n";
> close(DNS_UPDATE_LIST);
>
> + print "DONE\n";
> +
> $ret{SERVER_IP} = $server_ip;
> $ret{SERVER_IPV6} = $server_ipv6;
> $ret{NMBD_TEST_LOG} = "$prefix/nmbd_test.log";
> diff --git a/source3/script/tests/test_dfree_quota.sh b/source3/script/tests/test_dfree_quota.sh
> index 79b8d7c..6e227c4 100755
> --- a/source3/script/tests/test_dfree_quota.sh
> +++ b/source3/script/tests/test_dfree_quota.sh
> @@ -5,7 +5,7 @@
>
> if [ $# -lt 6 ]; then
> cat <<EOF
> -Usage: test_dfree_quota.sh SERVER DOMAIN USERNAME PASSWORD LOCAL_PATH SMBCLIENT SMBCQUOTAS
> +Usage: test_dfree_quota.sh SERVER DOMAIN USERNAME PASSWORD LOCAL_PATH SMBCLIENT SMBCQUOTAS SMBCACLS
> EOF
> exit 1;
> fi
> @@ -18,7 +18,8 @@ ENVDIR=`dirname $5`
> WORKDIR=$5/dfree
> smbclient=$6
> smbcquotas=$7
> -shift 7
> +smbcacls=$8
> +shift 8
> failed=0
>
> CONFFILE=$ENVDIR/lib/dfq.conf
> @@ -35,6 +36,8 @@ conf_lines() {
> local gid
> uid=$(id -u $USERNAME)
> gid=$(id -g $USERNAME)
> + uid1=$(id -u user1)
> + uid2=$(id -u user2)
> cat <<ABC
> conf1:df:block size = 512:disk free = 10:disk size = 20
> conf2:df:block size = 1024:disk free = 10:disk size = 20
> @@ -70,6 +73,9 @@ notenforce:udflt:block size = 4096:qflags = 0
> nfs:df:block size = 4096:disk free = 10:disk size = 80
> nfs:u$uid:block size = 4096:hard limit = 40:soft limit = 40:cur blocks = 37
> nfs:udflt:nosys = 1
> +confdfqp:df:block size = 4096:disk free = 10:disk size = 80
> +confdfqp:u$uid1:block size = 4096:hard limit = 40:soft limit = 40:cur blocks = 36
> +confdfqp:u$uid2:block size = 4096:hard limit = 41:soft limit = 41:cur blocks = 36
> ABC
> }
>
> @@ -185,5 +191,32 @@ test_smbclient_dfree "Test dfree share root quota not enforced" dfq "." "notenfo
> #FS quota not implemented (NFS case)
> test_smbclient_dfree "Test dfree share root FS quota not implemented" dfq "." "nfs ." "160 1024. 12" -U$USERNAME%$PASSWORD --option=clientmaxprotocol=SMB3 || failed=`expr $failed + 1`
>
> +#test for dfree when owner is inherited
> +#setup two folders with different owners
> +rm -rf $WORKDIR/subdir3/*
> +for d in / subdir3
> +do
> + $VALGRIND $smbcacls -U$USERNAME%$PASSWORD -D "ACL:$SERVER\user1:ALLOWED/0x0/FULL" //$SERVER/dfq $d > /dev/null 2>&1
> + $VALGRIND $smbcacls -U$USERNAME%$PASSWORD -a "ACL:$SERVER\user1:ALLOWED/0x0/FULL" //$SERVER/dfq $d || failed=`expr $failed + 1`
> + $VALGRIND $smbcacls -U$USERNAME%$PASSWORD -D "ACL:$SERVER\user2:ALLOWED/0x0/FULL" //$SERVER/dfq $d > /dev/null 2>&1
> + $VALGRIND $smbcacls -U$USERNAME%$PASSWORD -a "ACL:$SERVER\user2:ALLOWED/0x0/FULL" //$SERVER/dfq $d || failed=`expr $failed + 1`
> +done
> +
> +$VALGRIND $smbclient //$SERVER/dfq -c "cd subdir3; mkdir user1" -Uuser1%$PASSWORD --option=clientmaxprotocol=SMB3 > /dev/null 2>&1 || failed=`expr $failed + 1`
> +$VALGRIND $smbclient //$SERVER/dfq -c "cd subdir3; mkdir user2" -Uuser2%$PASSWORD --option=clientmaxprotocol=SMB3 > /dev/null 2>&1 || failed=`expr $failed + 1`
> +#test quotas
> +test_smbclient_dfree "Test dfree without inherit owner - user1 at user1" \
> + dfq "subdir3/user1" "confdfqp subdir3/user1 confdfqp subdir3/user2" "160 1024. 16" \
> + -Uuser1%$PASSWORD --option=clientmaxprotocol=SMB3 || failed=`expr $failed + 1`
> +test_smbclient_dfree "Test dfree without inherit owner - user1 at user2" \
> + dfq "subdir3/user2" "confdfqp subdir3/user1 confdfqp subdir3/user2" "160 1024. 16" \
> + -Uuser1%$PASSWORD --option=clientmaxprotocol=SMB3 || failed=`expr $failed + 1`
> +test_smbclient_dfree "Test dfree with inherit owner - user1 at user1" \
> + dfq_owner "subdir3/user1" "confdfqp subdir3/user1 confdfqp subdir3/user2" "160 1024. 16" \
> + -Uuser1%$PASSWORD --option=clientmaxprotocol=SMB3 || failed=`expr $failed + 1`
> +test_smbclient_dfree "Test dfree with inherit owner - user1 at user2" \
> + dfq_owner "subdir3/user2" "confdfqp subdir3/user1 confdfqp subdir3/user2" "164 1024. 20" \
> + -Uuser1%$PASSWORD --option=clientmaxprotocol=SMB3 || failed=`expr $failed + 1`
> +
> setup_conf
> exit $failed
> diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py
> index 23fb37d..0a0cb08 100755
> --- a/source3/selftest/tests.py
> +++ b/source3/selftest/tests.py
> @@ -184,7 +184,7 @@ for env in ["nt4_dc"]:
> for env in ["fileserver"]:
> plantestsuite("samba3.blackbox.preserve_case (%s)" % env, env, [os.path.join(samba3srcdir, "script/tests/test_preserve_case.sh"), '$SERVER', '$DOMAIN', '$USERNAME', '$PASSWORD', '$PREFIX', smbclient3])
> plantestsuite("samba3.blackbox.dfree_command (%s)" % env, env, [os.path.join(samba3srcdir, "script/tests/test_dfree_command.sh"), '$SERVER', '$DOMAIN', '$USERNAME', '$PASSWORD', '$PREFIX', smbclient3])
> - plantestsuite("samba3.blackbox.dfree_quota (%s)" % env, env, [os.path.join(samba3srcdir, "script/tests/test_dfree_quota.sh"), '$SERVER', '$DOMAIN', '$USERNAME', '$PASSWORD', '$LOCAL_PATH', smbclient3, smbcquotas])
> + plantestsuite("samba3.blackbox.dfree_quota (%s)" % env, env, [os.path.join(samba3srcdir, "script/tests/test_dfree_quota.sh"), '$SERVER', '$DOMAIN', '$USERNAME', '$PASSWORD', '$LOCAL_PATH', smbclient3, smbcquotas, smbcacls])
> plantestsuite("samba3.blackbox.valid_users (%s)" % env, env, [os.path.join(samba3srcdir, "script/tests/test_valid_users.sh"), '$SERVER', '$SERVER_IP', '$DOMAIN', '$USERNAME', '$PASSWORD', '$PREFIX', smbclient3])
> plantestsuite("samba3.blackbox.offline (%s)" % env, env, [os.path.join(samba3srcdir, "script/tests/test_offline.sh"), '$SERVER', '$SERVER_IP', '$DOMAIN', '$USERNAME', '$PASSWORD', '$LOCAL_PATH/offline', smbclient3])
> plantestsuite("samba3.blackbox.shadow_copy2 (%s)" % env, env, [os.path.join(samba3srcdir, "script/tests/test_shadow_copy.sh"), '$SERVER', '$SERVER_IP', '$DOMAIN', '$USERNAME', '$PASSWORD', '$LOCAL_PATH/shadow', smbclient3])
> --
> 2.5.5
>
More information about the samba-technical
mailing list