From 026fabc67efb9c205b654e2a45e9bd35880e53a6 Mon Sep 17 00:00:00 2001 From: Uri Simchoni Date: Wed, 27 Jan 2016 08:12:20 +0200 Subject: [PATCH 1/6] quotas: small cleanup Remove an internal function from proto.h BUG: https://bugzilla.samba.org/show_bug.cgi?id=12145 Signed-off-by: Uri Simchoni Reviewed-by: Jeremy Allison (cherry picked from commit 3e6ea02d4258a782482eee9f9124c6a39b74a965) --- source3/smbd/proto.h | 1 - 1 file changed, 1 deletion(-) diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h index 1ef84a0..6931bd8 100644 --- a/source3/smbd/proto.h +++ b/source3/smbd/proto.h @@ -830,7 +830,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 57ae01045ff156ed8d6e59e5390d1caacad66f34 Mon Sep 17 00:00:00 2001 From: Uri Simchoni Date: Thu, 14 Jan 2016 00:09:36 +0200 Subject: [PATCH 2/6] 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 Reviewed-by: Jeremy Allison (cherry picked from commit bd2ec88dca692c239397891bd35c9fa6b8e7b51a) --- 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 d51499d..2c02ae5 100644 --- a/source3/modules/vfs_ceph.c +++ b/source3/modules/vfs_ceph.c @@ -817,9 +817,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 6a0872c..8838104 100644 --- a/source3/modules/vfs_default.c +++ b/source3/modules/vfs_default.c @@ -1920,9 +1920,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 765fbe6..c1c42eb 100644 --- a/source3/smbd/dfree.c +++ b/source3/smbd/dfree.c @@ -49,7 +49,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; @@ -58,6 +58,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; @@ -123,7 +124,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; @@ -167,18 +168,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)) { @@ -189,7 +187,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 6931bd8..2790028 100644 --- a/source3/smbd/proto.h +++ b/source3/smbd/proto.h @@ -171,13 +171,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 */ @@ -828,8 +825,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 d71b0a0..cbe143d 100644 --- a/source3/smbd/quotas.c +++ b/source3/smbd/quotas.c @@ -236,8 +236,8 @@ try to get the disk space from disk quotas (SunOS & Solaris2 version) Quota code by Peter Urbanec (amiga@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; @@ -254,14 +254,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 defined(SUNOS5) @@ -426,15 +423,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 */ @@ -657,8 +655,8 @@ bool disk_quotas_vxfs(const char *name, char *path, uint64_t *bsize, uint64_t *d #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 */ @@ -676,8 +674,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; @@ -690,7 +688,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; } @@ -701,7 +700,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); /* Use softlimit to determine disk space, except when it has been exceeded */ *bsize = D.bsize; @@ -744,7 +744,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; } @@ -755,7 +756,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); /* Use softlimit to determine disk space, except when it has been exceeded */ *bsize = D.bsize; diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 4c0a331..72fa5a4 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 7354bba..09392a3 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -3377,8 +3377,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); } @@ -3528,8 +3528,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); } @@ -3562,8 +3562,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 89f0ae1..93726bd 100644 --- a/source3/smbd/vfs.c +++ b/source3/smbd/vfs.c @@ -593,8 +593,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 80828cb3160810a1e654ce5ed097cd2544209033 Mon Sep 17 00:00:00 2001 From: Uri Simchoni Date: Thu, 11 Aug 2016 23:37:42 +0300 Subject: [PATCH 3/6] 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 Reviewed-by: Jeremy Allison (backported from commit ea73bcd87b6113f77ccda683d15b5a39003b8eaa) --- 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 cbe143d..542ee36 100644 --- a/source3/smbd/quotas.c +++ b/source3/smbd/quotas.c @@ -700,8 +700,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)) && + 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); + } /* Use softlimit to determine disk space, except when it has been exceeded */ *bsize = D.bsize; -- 2.5.5 From e8db7b67c03c16a6697797ec0ccecd6fffff5048 Mon Sep 17 00:00:00 2001 From: Uri Simchoni Date: Wed, 20 Jan 2016 21:54:24 +0200 Subject: [PATCH 4/6] 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 Reviewed-by: Jeremy Allison (backported from commit f20d57eceacccb365892dec816cbe57e2ddda8b9) --- 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 26199cc..662e15a 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,37 +151,37 @@ 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 edquot" "subdir1" "edquot subdir1" "164 1024. 0" -U$USERNAME%$PASSWORD --option=clientmaxprotocol=SMB3 || failed=`expr $failed + 1` -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 edquot" dfq "subdir1" "edquot subdir1" "164 1024. 0" -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` #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 b7b9a7dc4cfc0ac9139adc0edcda730d462d6835 Mon Sep 17 00:00:00 2001 From: Uri Simchoni Date: Sun, 14 Aug 2016 14:54:11 +0300 Subject: [PATCH 5/6] selftest: add definition of smbcacls to selftesthelpers.py This facilitates cherry-picking of the next patch. BUG: https://bugzilla.samba.org/show_bug.cgi?id=12145 Signed-off-by: Uri Simchoni Reviewed-by: Jeremy Allison --- selftest/selftesthelpers.py | 1 + 1 file changed, 1 insertion(+) diff --git a/selftest/selftesthelpers.py b/selftest/selftesthelpers.py index 42499b0..7223ca1 100644 --- a/selftest/selftesthelpers.py +++ b/selftest/selftesthelpers.py @@ -185,3 +185,4 @@ dbwrap_tool = binpath('dbwrap_tool') vfstest = binpath('vfstest') smbcquotas = binpath('smbcquotas') smbget = binpath('smbget') +smbcacls = binpath('smbcacls') -- 2.5.5 From 54106853a7bd6cf7189f471a9cf3562de9cb26fa Mon Sep 17 00:00:00 2001 From: Uri Simchoni Date: Thu, 11 Aug 2016 23:54:22 +0300 Subject: [PATCH 6/6] selftest: add tests for dfree with inherit owner enabled BUG: https://bugzilla.samba.org/show_bug.cgi?id=12145 Signed-off-by: Uri Simchoni Reviewed-by: Jeremy Allison (cherry picked from commit b6931d5edc381d64ba0fbcd85538cd65e90a2560) --- 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 65b3a83..82bd5b8 100755 --- a/selftest/target/Samba3.pm +++ b/selftest/target/Samba3.pm @@ -603,6 +603,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); @@ -1089,7 +1090,6 @@ sub createuser($$$$) warn("Unable to set password for $username account\n$cmd"); return undef; } - print "DONE\n"; } sub provision($$$$$$$$) @@ -1319,8 +1319,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; @@ -1334,6 +1336,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; @@ -1687,9 +1691,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); @@ -1715,6 +1724,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 @@ -1789,12 +1800,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 662e15a..51ab3b1 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 < /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 72eaa53..7cbd16a 100755 --- a/source3/selftest/tests.py +++ b/source3/selftest/tests.py @@ -182,7 +182,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