The branch, master has been updated
       via  f1b42ec smbd: Fix snapshot query on shares with DFS enabled
       via  b6931d5 selftest: add tests for dfree with inherit owner enabled
       via  f20d57e selftest: refactor test_dfree_quota.sh - add share parameter
       via  ea73bcd smbd: use owner uid for free disk calculation if owner is 
inherited
       via  bd2ec88 smbd: get a valid file stat to disk_quotas
       via  3e6ea02 quotas: small cleanup
      from  1c10c85 ctdb: Fix the O3 developer build on RHEL7

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


- Log -----------------------------------------------------------------
commit f1b42ec778e08875e076df7fdf67dd69bf9b2757
Author: Christof Schmitt <c...@samba.org>
Date:   Fri Aug 12 14:59:07 2016 -0700

    smbd: Fix snapshot query on shares with DFS enabled
    
    When DFS is enabled (host msdfs = yes and msdfs root = yes), then SMB
    clients send create requests in the format \hostname\service\path.
    Putting the GMT tag as first element breaks the DFS parsing and results
    in OBJECT_NOT_FOUND for snapshotted files.  Fix this by appending the
    GMT tag to the end of the path.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=12150
    
    Signed-off-by: Christof Schmitt <c...@samba.org>
    Reviewed-by: Jeremy Allison <j...@samba.org>
    
    Autobuild-User(master): Jeremy Allison <j...@samba.org>
    Autobuild-Date(master): Sat Aug 13 05:44:39 CEST 2016 on sn-devel-144

commit b6931d5edc381d64ba0fbcd85538cd65e90a2560
Author: Uri Simchoni <u...@samba.org>
Date:   Thu Aug 11 23:54:22 2016 +0300

    selftest: add tests for dfree with inherit owner enabled
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=12145
    
    Signed-off-by: Uri Simchoni <u...@samba.org>
    Reviewed-by: Jeremy Allison <j...@samba.org>

commit f20d57eceacccb365892dec816cbe57e2ddda8b9
Author: Uri Simchoni <u...@samba.org>
Date:   Wed Jan 20 21:54:24 2016 +0200

    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 <u...@samba.org>
    Reviewed-by: Jeremy Allison <j...@samba.org>

commit ea73bcd87b6113f77ccda683d15b5a39003b8eaa
Author: Uri Simchoni <u...@samba.org>
Date:   Thu Aug 11 23:37:42 2016 +0300

    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 <u...@samba.org>
    Reviewed-by: Jeremy Allison <j...@samba.org>

commit bd2ec88dca692c239397891bd35c9fa6b8e7b51a
Author: Uri Simchoni <u...@samba.org>
Date:   Thu Jan 14 00:09:36 2016 +0200

    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 <u...@samba.org>
    Reviewed-by: Jeremy Allison <j...@samba.org>

commit 3e6ea02d4258a782482eee9f9124c6a39b74a965
Author: Uri Simchoni <u...@samba.org>
Date:   Wed Jan 27 08:12:20 2016 +0200

    quotas: small cleanup
    
    Remove an internal function from proto.h
    
    Signed-off-by: Uri Simchoni <u...@samba.org>
    Reviewed-by: Jeremy Allison <j...@samba.org>

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

Summary of changes:
 selftest/target/Samba3.pm                | 21 ++++++--
 source3/modules/vfs_ceph.c               |  5 +-
 source3/modules/vfs_default.c            |  5 +-
 source3/script/tests/test_dfree_quota.sh | 84 ++++++++++++++++++++++----------
 source3/selftest/tests.py                |  2 +-
 source3/smbd/dfree.c                     | 16 +++---
 source3/smbd/proto.h                     | 16 +++---
 source3/smbd/quotas.c                    | 55 ++++++++++++++-------
 source3/smbd/reply.c                     | 13 ++++-
 source3/smbd/smb2_create.c               |  6 +--
 source3/smbd/trans2.c                    | 12 ++---
 source3/smbd/vfs.c                       |  4 +-
 12 files changed, 155 insertions(+), 84 deletions(-)


Changeset truncated at 500 lines:

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/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/script/tests/test_dfree_quota.sh 
b/source3/script/tests/test_dfree_quota.sh
index ab28a07..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
 }
 
@@ -99,16 +105,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 +157,66 @@ 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`
+
+#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])
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 97fe577..fb30a9e 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  */
 
@@ -855,9 +852,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_vxfs(const char *name, 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..2db18cd 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 (am...@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,25 @@ 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);
+       /* 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;
@@ -543,7 +560,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 +572,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,


-- 
Samba Shared Repository

Reply via email to