[SCM] Samba Shared Repository - branch master updated

Jeremy Allison jra at samba.org
Tue Oct 10 00:58:02 UTC 2017


The branch, master has been updated
       via  76a1c5a wbinfo: return "NOT MAPPED" instead of "S-0-0" for unmapped id-to-sid
       via  0666093 vfs_fake_acls: deny give-ownership
       via  7e7afef vfs_acl_common: fix take ownership vs give ownership
       via  e62f90a vfs_acl_common: factor out a variable declaration
       via  cc555be s3/smbd/posix_acls: return correct status in try_chown
       via  4b2e171 selftest: tests for change ownership on a file
       via  ff199d8 selftest: fix samba3.blackbox.inherit_owner.default test script test_inherit_owner.sh
       via  3aff631 selftest: fix acl_xattr test script test_acl_xattr.sh
       via  ea0ea82 selftest: fix acl_xattr test: sn-devel unreliable gid
       via  1fabe25 selftest: fix acl_xattr test: grep ouput before munging
       via  71a2d06 selftest: fix acl_xattr test: group, not user
       via  0f8de2d selftest: fix acl_xattr test: changing owner
       via  272f1c9 s3: smbd: Currently if getwd() fails after a chdir(), we panic.
      from  a826394 smbcacls: no need to fetch the sd when changing ownership

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


- Log -----------------------------------------------------------------
commit 76a1c5a1625f3593de0feac47741a3405b4c9275
Author: Ralph Boehme <slow at samba.org>
Date:   Mon Oct 9 13:25:21 2017 +0200

    wbinfo: return "NOT MAPPED" instead of "S-0-0" for unmapped id-to-sid
    
    Currently wbinfo --unix-ids-to-sids prints "S-0-0" for failed
    mappings. Let it print "NOT MAPPED" instead.
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    
    Autobuild-User(master): Jeremy Allison <jra at samba.org>
    Autobuild-Date(master): Tue Oct 10 02:57:40 CEST 2017 on sn-devel-144

commit 0666093cb0d820cc27a265c1f0a87bc76cd3c167
Author: Ralph Boehme <slow at samba.org>
Date:   Fri Oct 6 15:25:54 2017 +0200

    vfs_fake_acls: deny give-ownership
    
    Windows doesn't allow giving ownership away unless the user has
    SEC_PRIV_RESTORE privilege.
    
    This follows from MS-FSA 2.1.5.1, so it's a property of the filesystem
    layer, not the SMB layer. By implementing this restriction here, we can
    now have test for this restriction.
    
    Other filesystems may want to deliberately allow this behaviour --
    although I'm not aware of any that does -- therefor I'm putting in this
    restriction in the implementation of the chmod VFS function and not into
    the caller.
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=7933
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 7e7afef819b4a858e6de48389c6f4fa7510cf5c6
Author: Ralph Boehme <slow at samba.org>
Date:   Wed Oct 4 22:27:24 2017 +0200

    vfs_acl_common: fix take ownership vs give ownership
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=7933
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit e62f90a6d15626a2e20ba92f5cd552101ec4afe0
Author: Ralph Boehme <slow at samba.org>
Date:   Wed Oct 4 12:51:29 2017 +0200

    vfs_acl_common: factor out a variable declaration
    
    Just some refactoring, no change in behaviour.
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=7933
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit cc555be4d01c4140445bd30e16be3fe8343d3872
Author: Ralph Boehme <slow at samba.org>
Date:   Wed Oct 4 15:45:54 2017 +0200

    s3/smbd/posix_acls: return correct status in try_chown
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=7933
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 4b2e171e6b90f9c3594ebb705a28c66b981c2bf5
Author: Ralph Boehme <slow at samba.org>
Date:   Fri Oct 6 15:31:20 2017 +0200

    selftest: tests for change ownership on a file
    
    This test verifies that SEC_STD_WRITE_OWNER only effectively grants
    take-ownership permissions but NOT give-ownership. The latter requires
    SeRestorePrivilege privilege.
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=7933
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit ff199d8e3ea7bd1ed12de8c39340ba640a2b83ca
Author: Ralph Boehme <slow at samba.org>
Date:   Sat Oct 7 09:11:56 2017 +0200

    selftest: fix samba3.blackbox.inherit_owner.default test script test_inherit_owner.sh
    
    Grant the test-user SeRestorePrivilege, this is needed for
    give-ownership operations. And then granting SeRestorePrivilege requires
    `net`, so add that as an additional argument to the script.
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=7933
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 3aff6315097cc9db0216bc18aa793a996930b0f4
Author: Ralph Boehme <slow at samba.org>
Date:   Sun Oct 8 11:17:12 2017 +0200

    selftest: fix acl_xattr test script test_acl_xattr.sh
    
    The two "nt_affects_chgrp" tests called the wrong function so the
    function nt_affects_chgrp() was never run.
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=7933
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit ea0ea829f5af63ab9638e758631c3002cbb6b4ce
Author: Ralph Boehme <slow at samba.org>
Date:   Sun Oct 8 08:51:05 2017 +0200

    selftest: fix acl_xattr test: sn-devel unreliable gid
    
    The "nt_affects_chgrp" kept failing in a full autobuild on sn-devel
    because the actual gid of the created file as returned by smbclient -c
    getfacl was reliably the unix gid of my account. It should have been the
    mapped domusers group for the primary users "Domain Users"
    group. Running the test individually or even the full set of
    "samba3.blackbox" tests didn't trigger the error.
    
    Looks like an issue with vfs_fake_acls and vfs_xattr_tdb, but I wasn't
    able to track it down. As the test only really want to ensure that
    smbcacls -G set the gid to the requested value, just remove the check
    for the actual initial gid.
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=7933
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 1fabe25339166e381ab0e118667f9c19781b49df
Author: Ralph Boehme <slow at samba.org>
Date:   Sun Oct 8 11:16:27 2017 +0200

    selftest: fix acl_xattr test: grep ouput before munging
    
    The check of the smbclient getfacl output for presence of a "^# group:"
    line must be done before munging the saved output with a sed filter.
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=7933
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 71a2d06a1e41a1c412c82e58b3966e14c29c6159
Author: Ralph Boehme <slow at samba.org>
Date:   Sun Oct 8 11:13:46 2017 +0200

    selftest: fix acl_xattr test: group, not user
    
    In nt_affects_chgrp() check for domadmins *group*, not user. This didn't
    trigger an error as nt_affects_chgrp() isn't actually called, see next
    commit.
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=7933
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 0f8de2dee5451c9791f96050f85e4f007bec2819
Author: Ralph Boehme <slow at samba.org>
Date:   Sun Oct 8 11:12:48 2017 +0200

    selftest: fix acl_xattr test: changing owner
    
    Don't give ownership to user "force_user" as user "$USERNAME", this
    would fail with NT_STATUS_INVALID_OWNER, instead just take ownership as
    user "force_user". Adding a corresponding ACE for "force_user" with FULL
    rights ensures this works.
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=7933
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 272f1c9febdf51dd6ec7b862d33d2010621e840a
Author: Jeremy Allison <jra at samba.org>
Date:   Wed Oct 4 12:43:22 2017 -0700

    s3: smbd: Currently if getwd() fails after a chdir(), we panic.
    
    Change this to return to the previous $cwd, and return -1 for the chdir().
    
    If the return to the previous $cwd fails, still panic as we
    can't return an unknown state.
    
    Also do early return from failing SMB_VFS_CHDIR, reducing indentation level
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13027
    
    Signed-off-by: Jeremy Allison <jra at samba.org>
    Signed-off-by: Ralph Böhme <slow at samba.org>

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

Summary of changes:
 nsswitch/tests/test_idmap_rfc2307.sh       |   2 +-
 nsswitch/wbinfo.c                          |   6 ++
 source3/modules/vfs_acl_common.c           |  18 ++++-
 source3/modules/vfs_fake_acls.c            |  18 +++++
 source3/script/tests/test_acl_xattr.sh     |  15 ++--
 source3/script/tests/test_give_owner.sh    | 121 +++++++++++++++++++++++++++++
 source3/script/tests/test_inherit_owner.sh |  17 ++--
 source3/selftest/tests.py                  |  13 ++--
 source3/smbd/posix_acls.c                  |   2 +-
 source3/smbd/vfs.c                         |  81 ++++++++++++++++---
 10 files changed, 259 insertions(+), 34 deletions(-)
 create mode 100755 source3/script/tests/test_give_owner.sh


Changeset truncated at 500 lines:

diff --git a/nsswitch/tests/test_idmap_rfc2307.sh b/nsswitch/tests/test_idmap_rfc2307.sh
index 35daa39..7dc697d 100755
--- a/nsswitch/tests/test_idmap_rfc2307.sh
+++ b/nsswitch/tests/test_idmap_rfc2307.sh
@@ -179,7 +179,7 @@ while [ ${i} -lt ${NUMGROUPS} ] ; do
     GIDS="$GIDS g$(expr ${i} + ${GID_START})"
     i=$(expr "$i" + 1)
 done
-NUM_VALID_SIDS=$($wbinfo --unix-ids-to-sids="$GIDS" | grep -v ^S-0-0 | wc -l)
+NUM_VALID_SIDS=$($wbinfo --unix-ids-to-sids="$GIDS" | grep -v ^"NOT MAPPED" | wc -l)
 
 testit "Count number of valid sids found" \
        test ${NUM_VALID_SIDS} = ${NUMGROUPS} ||
diff --git a/nsswitch/wbinfo.c b/nsswitch/wbinfo.c
index 67a97b5..9cd299a 100644
--- a/nsswitch/wbinfo.c
+++ b/nsswitch/wbinfo.c
@@ -1105,6 +1105,12 @@ static bool wbinfo_xids_to_sids(const char *arg)
 
 	for (i=0; i<num_xids; i++) {
 		char str[WBC_SID_STRING_BUFLEN];
+		struct wbcDomainSid null_sid = { 0 };
+
+		if (memcmp(&null_sid, &sids[i], sizeof(struct wbcDomainSid)) == 0) {
+			d_printf("NOT MAPPED\n");
+			continue;
+		}
 		wbcSidToStringBuf(&sids[i], str, sizeof(str));
 		d_printf("%s\n", str);
 	}
diff --git a/source3/modules/vfs_acl_common.c b/source3/modules/vfs_acl_common.c
index c4849b6..7958fd1 100644
--- a/source3/modules/vfs_acl_common.c
+++ b/source3/modules/vfs_acl_common.c
@@ -1018,8 +1018,10 @@ static NTSTATUS set_underlying_acl(vfs_handle_struct *handle, files_struct *fsp,
 				   uint32_t security_info_sent,
 				   bool chown_needed)
 {
-	NTSTATUS status =
-	    SMB_VFS_NEXT_FSET_NT_ACL(handle, fsp, security_info_sent, psd);
+	NTSTATUS status;
+	const struct security_token *token = NULL;
+
+	status = SMB_VFS_NEXT_FSET_NT_ACL(handle, fsp, security_info_sent, psd);
 	if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
 		return status;
 	}
@@ -1032,6 +1034,18 @@ static NTSTATUS set_underlying_acl(vfs_handle_struct *handle, files_struct *fsp,
 		return NT_STATUS_ACCESS_DENIED;
 	}
 
+	/*
+	 * Only allow take-ownership, not give-ownership. That's the way Windows
+	 * implements SEC_STD_WRITE_OWNER. MS-FSA 2.1.5.16 just states: If
+	 * InputBuffer.OwnerSid is not a valid owner SID for a file in the
+	 * objectstore, as determined in an implementation specific manner, the
+	 * object store MUST return STATUS_INVALID_OWNER.
+	 */
+	token = get_current_nttok(fsp->conn);
+	if (!security_token_is_sid(token, psd->owner_sid)) {
+		return NT_STATUS_INVALID_OWNER;
+	}
+
 	DBG_DEBUG("overriding chown on file %s for sid %s\n",
 		   fsp_str_dbg(fsp), sid_string_tos(psd->owner_sid));
 
diff --git a/source3/modules/vfs_fake_acls.c b/source3/modules/vfs_fake_acls.c
index 7de5cf0..0f539d1 100644
--- a/source3/modules/vfs_fake_acls.c
+++ b/source3/modules/vfs_fake_acls.c
@@ -413,6 +413,12 @@ static int fake_acls_chown(vfs_handle_struct *handle,
 	int ret;
 	uint8_t id_buf[4];
 	if (uid != -1) {
+		uid_t current_uid = get_current_uid(handle->conn);
+
+		if (current_uid != 0 && current_uid != uid) {
+			return EACCES;
+		}
+
 		SIVAL(id_buf, 0, uid);
 		ret = SMB_VFS_NEXT_SETXATTR(handle,
 				smb_fname,
@@ -447,6 +453,12 @@ static int fake_acls_lchown(vfs_handle_struct *handle,
 	int ret;
 	uint8_t id_buf[4];
 	if (uid != -1) {
+		uid_t current_uid = get_current_uid(handle->conn);
+
+		if (current_uid != 0 && current_uid != uid) {
+			return EACCES;
+		}
+
 		/* This isn't quite right (calling setxattr not
 		 * lsetxattr), but for the test purposes of this
 		 * module (fake NT ACLs from windows clients), it is
@@ -486,6 +498,12 @@ static int fake_acls_fchown(vfs_handle_struct *handle, files_struct *fsp, uid_t
 	int ret;
 	uint8_t id_buf[4];
 	if (uid != -1) {
+		uid_t current_uid = get_current_uid(handle->conn);
+
+		if (current_uid != 0 && current_uid != uid) {
+			return EACCES;
+		}
+
 		SIVAL(id_buf, 0, uid);
 		ret = SMB_VFS_NEXT_FSETXATTR(handle, fsp, FAKE_UID, id_buf, sizeof(id_buf), 0);
 		if (ret != 0) {
diff --git a/source3/script/tests/test_acl_xattr.sh b/source3/script/tests/test_acl_xattr.sh
index ddccf4f..cba7912 100755
--- a/source3/script/tests/test_acl_xattr.sh
+++ b/source3/script/tests/test_acl_xattr.sh
@@ -77,7 +77,8 @@ nt_affects_chown() {
     b4_actual=$($SMBCLIENT //$SERVER/$share -U $USERNAME%$PASSWORD -c "getfacl $fname" 2>/dev/null) || exit 1
     echo "${b4_actual}" | grep -q "^# owner:" || exit 1
     b4_actual=$(echo "$b4_actual" | sed -rn 's/^# owner: (.*)/\1/p')
-    $SMBCACLS //$SERVER/$share $fname -U $USERNAME%$PASSWORD -C force_user 2>/dev/null || exit 1
+    $SMBCACLS //$SERVER/$share $fname -U $USERNAME%$PASSWORD -a "ACL:$SERVER\force_user:ALLOWED/0x0/FULL" || exit 1
+    $SMBCACLS //$SERVER/$share $fname -U force_user%$PASSWORD -C force_user 2>/dev/null || exit 1
     af_actual=$($SMBCLIENT //$SERVER/$share -U $USERNAME%$PASSWORD -c "getfacl $fname" 2>/dev/null) || exit 1
     echo "${af_actual}" | grep -q "^# owner:" || exit 1
     af_actual=$(echo "$af_actual" | sed -rn 's/^# owner: (.*)/\1/p')
@@ -99,8 +100,8 @@ nt_affects_chgrp() {
     b4_expected=$(echo "$b4_expected" | awk -F: '{print $3}')
     echo "$b4_expected"
 
-    echo -n "determining uid of domadmins..."
-    af_expected=$(getent passwd domadmins) || exit 1
+    echo -n "determining gid of domadmins..."
+    af_expected=$(getent group domadmins) || exit 1
     af_expected=$(echo "$af_expected" | awk -F: '{print $3}')
     echo "$af_expected"
 
@@ -108,15 +109,15 @@ nt_affects_chgrp() {
     test "$b4_expected" != "$af_expected" || exit 1
 
     b4_actual=$($SMBCLIENT //$SERVER/$share -U $USERNAME%$PASSWORD -c "getfacl $fname" 2>/dev/null) || exit 1
-    b4_actual=$(echo "$b4_actual" | sed -rn 's/^# group: (.*)/\1/p')
     echo "${b4_actual}" | grep -q "^# group:" || exit 1
+    b4_actual=$(echo "$b4_actual" | sed -rn 's/^# group: (.*)/\1/p')
     $SMBCACLS //$SERVER/$share $fname -U $USERNAME%$PASSWORD -G domadmins 2>/dev/null || exit 1
     af_actual=$($SMBCLIENT //$SERVER/$share -U $USERNAME%$PASSWORD -c "getfacl $fname" 2>/dev/null) || exit 1
     echo "${af_actual}" | grep -q "^# group:" || exit 1
     af_actual=$(echo "$af_actual" | sed -rn 's/^# group: (.*)/\1/p')
     echo "before: $b4_actual"
     echo "after: $af_actual"
-    test "$b4_expected" = "$b4_actual" && test "$af_expected" = "$af_actual"
+    test "$af_expected" != "$b4_actual" && test "$af_expected" = "$af_actual"
 }
 
 testit "setup remote file tmp" setup_remote_file tmp
@@ -129,5 +130,5 @@ testit "nt_affects_chown tmp" nt_affects_chown tmp
 testit "nt_affects_chown ign_sysacls" nt_affects_chown ign_sysacls
 testit "setup remote file tmp" setup_remote_file tmp
 testit "setup remote file ign_sysacls" setup_remote_file ign_sysacls
-testit "nt_affects_chgrp tmp" nt_affects_chown tmp
-testit "nt_affects_chgrp ign_sysacls" nt_affects_chown ign_sysacls
+testit "nt_affects_chgrp tmp" nt_affects_chgrp tmp
+testit "nt_affects_chgrp ign_sysacls" nt_affects_chgrp ign_sysacls
diff --git a/source3/script/tests/test_give_owner.sh b/source3/script/tests/test_give_owner.sh
new file mode 100755
index 0000000..64e09f3
--- /dev/null
+++ b/source3/script/tests/test_give_owner.sh
@@ -0,0 +1,121 @@
+#!/bin/sh
+#
+# this verifies that SEC_STD_WRITE_OWNER only effectively grants take-ownership
+# permissions but NOT give-ownership.
+#
+
+if [ $# -lt 9 ]; then
+    echo "Usage: $0 SERVER SERVER_IP USERNAME PASSWORD PREFIX SMBCLIENT SMBCACLS NET SHARE"
+    exit 1
+fi
+
+SERVER="$1"
+SERVER_IP="$2"
+USERNAME="$3"
+PASSWORD="$4"
+PREFIX="$5"
+SMBCLIENT="$6"
+SMBCACLS="$7"
+NET="$8"
+SHARE="$9"
+
+SMBCLIENT="$VALGRIND ${SMBCLIENT}"
+SMBCACLS="$VALGRIND ${SMBCACLS}"
+NET="$VALGRIND ${NET}"
+failed=0
+
+incdir=`dirname $0`/../../../testprogs/blackbox
+. $incdir/subunit.sh
+
+setup_testfile() {
+    local share=$1
+    local fname=$2
+    touch $PREFIX/$fname
+    $SMBCLIENT //$SERVER/$share -U $USERNAME%$PASSWORD -c "rm $fname"
+    $SMBCLIENT //$SERVER/$share -U $USERNAME%$PASSWORD -c "ls" | grep "$fname" && return 1
+    $SMBCLIENT //$SERVER/$share -U $USERNAME%$PASSWORD -c "lcd $PREFIX; put $fname" || return 1
+}
+
+remove_testfile() {
+    local share=$1
+    local fname=$2
+    $SMBCLIENT //$SERVER/$share -U $USERNAME%$PASSWORD -c "rm $fname"
+}
+
+set_win_owner() {
+    local share=$1
+    local fname=$2
+    local owner=$3
+    echo "$SMBCACLS //$SERVER/$share $fname -U $USERNAME%$PASSWORD -C '$owner'"
+    $SMBCACLS //$SERVER/$share $fname -U $USERNAME%$PASSWORD -C "$owner" || return 1
+}
+
+win_owner_is() {
+    local share=$1
+    local fname=$2
+    local expected_owner=$3
+    local actual_owner
+
+    echo "$SMBCACLS //$SERVER/$share $fname -U $USERNAME%$PASSWORD"
+    $SMBCACLS //$SERVER/$share $fname -U $USERNAME%$PASSWORD
+    actual_owner=$($SMBCACLS //$SERVER/$share $fname -U $USERNAME%$PASSWORD | sed -rn 's/^OWNER:(.*)/\1/p')
+    echo "actual_owner = $actual_owner"
+    if ! test "x$actual_owner" = "x$expected_owner" ; then
+        echo "Actual owner of $share/$fname is [$actual_owner] expected [$expected_owner]"
+        return 1
+    fi
+    return 0
+}
+
+add_ace() {
+    local share=$1
+    local fname=$2
+    local ace=$3
+
+    local_ace=$(echo $ace | sed 's|\\|/|')
+
+    # avoid duplicate
+    out=$($SMBCACLS //$SERVER/$share $fname -U $USERNAME%$PASSWORD)
+    echo "$out" | grep "$local_ace" && return 0
+
+    # add it
+    $SMBCACLS //$SERVER/$share $fname -U $USERNAME%$PASSWORD -a "$ace" || return 1
+
+    # check it's there
+    out=$($SMBCACLS //$SERVER/$share $fname -U $USERNAME%$PASSWORD) || return 1
+    echo "$out" | grep "$local_ace" || return 1
+}
+
+chown_give_fails() {
+    local share=$1
+    local fname=$2
+    local user=$3
+    local expected_error=$4
+
+    # this must fail
+    out=$($SMBCACLS //$SERVER/$share $fname -U $USERNAME%$PASSWORD -C "$user") && return 1
+    # it failed, now check it returned the expected error code
+    echo "$out" | grep $expected_error || return 1
+}
+
+# Create a testfile
+testit "create testfile" setup_testfile $SHARE afile || failed=`expr $failed + 1`
+testit "verify owner" win_owner_is $SHARE afile "$SERVER/$USERNAME" || failed=`expr $failed + 1`
+
+# Grant SeRestorePrivilege to the user and full rights on the file
+testit "grant SeRestorePrivilege" $NET rpc rights grant $USERNAME SeRestorePrivilege -U $USERNAME%$PASSWORD -I $SERVER_IP || failed=`expr $failed + 1`
+testit "grant full rights" add_ace $SHARE afile "ACL:$SERVER\\$USERNAME:ALLOWED/0x0/FULL" || failed=`expr $failed + 1`
+
+# We have SeRestorePrivilege, so both give and take ownership must succeed
+testit "give owner with SeRestorePrivilege" set_win_owner $SHARE afile "$SERVER\user1" || failed=`expr $failed + 1`
+testit "verify owner" win_owner_is $SHARE afile "$SERVER/user1" || failed=`expr $failed + 1`
+testit "take owner" set_win_owner $SHARE afile "$SERVER\\$USERNAME" || failed=`expr $failed + 1`
+testit "verify owner" win_owner_is $SHARE afile "$SERVER/$USERNAME" || failed=`expr $failed + 1`
+
+# Revoke SeRestorePrivilege, give ownership must fail now with NT_STATUS_INVALID_OWNER
+testit "revoke SeRestorePrivilege" $NET rpc rights revoke $USERNAME SeRestorePrivilege -U $USERNAME%$PASSWORD -I $SERVER_IP || failed=`expr $failed + 1`
+testit "give owner without SeRestorePrivilege" chown_give_fails $SHARE afile "$SERVER\user1" NT_STATUS_INVALID_OWNER || failed=`expr $failed + 1`
+
+testit "delete testfile" remove_testfile $SHARE afile || failed=`expr $failed + 1`
+
+exit $failed
diff --git a/source3/script/tests/test_inherit_owner.sh b/source3/script/tests/test_inherit_owner.sh
index 5146d40..9f22a2c 100755
--- a/source3/script/tests/test_inherit_owner.sh
+++ b/source3/script/tests/test_inherit_owner.sh
@@ -4,9 +4,9 @@
 # currently needs to run in SMB1 mode, because it uses UNIX
 # extensions to fetch the UNIX owner of a file.
 
-if [ $# -lt 9 ]; then
+if [ $# -lt 10 ]; then
 cat <<EOF
-Usage: $0 SERVER USERNAME PASSWORD PREFIX SMBCLIENT SMBCACLS SHARE INH_WIN INH_UNIX <additional args>
+Usage: $0 SERVER USERNAME PASSWORD PREFIX SMBCLIENT SMBCACLS NET SHARE INH_WIN INH_UNIX <additional args>
 EOF
 exit 1;
 fi
@@ -17,13 +17,15 @@ PASSWORD="$3"
 PREFIX="$4"
 SMBCLIENT="$5"
 SMBCACLS="$6"
-SHARE="$7"
-INH_WIN="$8"
-INH_UNIX="$9"
-shift 9
+NET="$7"
+SHARE="$8"
+INH_WIN="$9"
+INH_UNIX="${10}"
+shift 10
 ADDARGS="$*"
 SMBCLIENT="$VALGRIND ${SMBCLIENT} ${ADDARGS}"
 SMBCACLS="$VALGRIND ${SMBCACLS} ${ADDARGS}"
+NET="$VALGRIND ${NET}"
 
 incdir=`dirname $0`/../../../testprogs/blackbox
 . $incdir/subunit.sh
@@ -137,6 +139,7 @@ fi
 
 # SETUP
 testit "$TEST_LABEL - setup root dir" create_dir tmp tmp.$$
+testit "grant SeRestorePrivilege" $NET rpc rights grant $USERNAME SeRestorePrivilege -U $USERNAME%$PASSWORD -I $SERVER || exit 1
 testit "$TEST_LABEL - assign default ACL" $SMBCACLS //$SERVER/tmp tmp.$$ -U $USERNAME%$PASSWORD -S "REVISION:1,OWNER:$SERVER\force_user,GROUP:$SERVER\domusers,ACL:Everyone:ALLOWED/0x3/FULL" 2>/dev/null
 # END SETUP
 
@@ -155,3 +158,5 @@ testit "$TEST_LABEL - verify file unix owner after change" unix_owner_id_is $SHA
 testit "$TEST_LABEL - cleanup subdir" cleanup_dir $SHARE tmp.$$/subdir
 testit "$TEST_LABEL - cleanup file" cleanup_file $SHARE tmp.$$/afile
 testit "$TEST_LABEL - cleanup root" cleanup_dir $SHARE tmp.$$
+
+testit "revoke SeRestorePrivilege" $NET rpc rights revoke $USERNAME SeRestorePrivilege -U $USERNAME%$PASSWORD -I $SERVER || exit 1
diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py
index 1c40e7e..8efc42c 100755
--- a/source3/selftest/tests.py
+++ b/source3/selftest/tests.py
@@ -252,14 +252,15 @@ for env in ["fileserver"]:
     plantestsuite("samba3.blackbox.acl_xattr.NT1", env, [os.path.join(samba3srcdir, "script/tests/test_acl_xattr.sh"), '$SERVER', '$USERNAME', '$PASSWORD', '$PREFIX', smbclient3, smbcacls, '-mNT1'])
     plantestsuite("samba3.blackbox.acl_xattr.SMB3", env, [os.path.join(samba3srcdir, "script/tests/test_acl_xattr.sh"), '$SERVER', '$USERNAME', '$PASSWORD', '$PREFIX', smbclient3, smbcacls, '-mSMB3'])
     plantestsuite("samba3.blackbox.smb2.not_casesensitive (%s)" % env, env, [os.path.join(samba3srcdir, "script/tests/test_smb2_not_casesensitive.sh"), '//$SERVER/tmp', '$SERVER_IP', '$USERNAME', '$PASSWORD', '$LOCAL_PATH', smbclient3])
-    plantestsuite("samba3.blackbox.inherit_owner.default.NT1", env, [os.path.join(samba3srcdir, "script/tests/test_inherit_owner.sh"), '$SERVER', '$USERNAME', '$PASSWORD', '$PREFIX', smbclient3, smbcacls, 'tmp', '0', '0', '-m', 'NT1'])
-    plantestsuite("samba3.blackbox.inherit_owner.default.SMB3", env, [os.path.join(samba3srcdir, "script/tests/test_inherit_owner.sh"), '$SERVER', '$USERNAME', '$PASSWORD', '$PREFIX', smbclient3, smbcacls, 'tmp', '0', '0', '-m', 'SMB3'])
-    plantestsuite("samba3.blackbox.inherit_owner.full.NT1", env, [os.path.join(samba3srcdir, "script/tests/test_inherit_owner.sh"), '$SERVER', '$USERNAME', '$PASSWORD', '$PREFIX', smbclient3, smbcacls, 'inherit_owner', '1', '1', '-m', 'NT1'])
-    plantestsuite("samba3.blackbox.inherit_owner.full.SMB3", env, [os.path.join(samba3srcdir, "script/tests/test_inherit_owner.sh"), '$SERVER', '$USERNAME', '$PASSWORD', '$PREFIX', smbclient3, smbcacls, 'inherit_owner', '1', '1', '-m', 'SMB3'])
-    plantestsuite("samba3.blackbox.inherit_owner.unix.NT1", env, [os.path.join(samba3srcdir, "script/tests/test_inherit_owner.sh"), '$SERVER', '$USERNAME', '$PASSWORD', '$PREFIX', smbclient3, smbcacls, 'inherit_owner_u', '0', '1', '-m', 'NT1'])
-    plantestsuite("samba3.blackbox.inherit_owner.unix.SMB3", env, [os.path.join(samba3srcdir, "script/tests/test_inherit_owner.sh"), '$SERVER', '$USERNAME', '$PASSWORD', '$PREFIX', smbclient3, smbcacls, 'inherit_owner_u', '0', '1', '-m', 'SMB3'])
+    plantestsuite("samba3.blackbox.inherit_owner.default.NT1", env, [os.path.join(samba3srcdir, "script/tests/test_inherit_owner.sh"), '$SERVER', '$USERNAME', '$PASSWORD', '$PREFIX', smbclient3, smbcacls, net, 'tmp', '0', '0', '-m', 'NT1'])
+    plantestsuite("samba3.blackbox.inherit_owner.default.SMB3", env, [os.path.join(samba3srcdir, "script/tests/test_inherit_owner.sh"), '$SERVER', '$USERNAME', '$PASSWORD', '$PREFIX', smbclient3, smbcacls, net, 'tmp', '0', '0', '-m', 'SMB3'])
+    plantestsuite("samba3.blackbox.inherit_owner.full.NT1", env, [os.path.join(samba3srcdir, "script/tests/test_inherit_owner.sh"), '$SERVER', '$USERNAME', '$PASSWORD', '$PREFIX', smbclient3, smbcacls, net, 'inherit_owner', '1', '1', '-m', 'NT1'])
+    plantestsuite("samba3.blackbox.inherit_owner.full.SMB3", env, [os.path.join(samba3srcdir, "script/tests/test_inherit_owner.sh"), '$SERVER', '$USERNAME', '$PASSWORD', '$PREFIX', smbclient3, smbcacls, net, 'inherit_owner', '1', '1', '-m', 'SMB3'])
+    plantestsuite("samba3.blackbox.inherit_owner.unix.NT1", env, [os.path.join(samba3srcdir, "script/tests/test_inherit_owner.sh"), '$SERVER', '$USERNAME', '$PASSWORD', '$PREFIX', smbclient3, smbcacls, net, 'inherit_owner_u', '0', '1', '-m', 'NT1'])
+    plantestsuite("samba3.blackbox.inherit_owner.unix.SMB3", env, [os.path.join(samba3srcdir, "script/tests/test_inherit_owner.sh"), '$SERVER', '$USERNAME', '$PASSWORD', '$PREFIX', smbclient3, smbcacls, net, 'inherit_owner_u', '0', '1', '-m', 'SMB3'])
     plantestsuite("samba3.blackbox.large_acl.NT1", env, [os.path.join(samba3srcdir, "script/tests/test_large_acl.sh"), '$SERVER', '$USERNAME', '$PASSWORD', smbclient3, smbcacls, '-m', 'NT1'])
     plantestsuite("samba3.blackbox.large_acl.SMB3", env, [os.path.join(samba3srcdir, "script/tests/test_large_acl.sh"), '$SERVER', '$USERNAME', '$PASSWORD', smbclient3, smbcacls, '-m', 'SMB3'])
+    plantestsuite("samba3.blackbox.give_owner", env, [os.path.join(samba3srcdir, "script/tests/test_give_owner.sh"), '$SERVER', '$SERVER_IP', '$USERNAME', '$PASSWORD', '$PREFIX', smbclient3, smbcacls, net, 'tmp'])
 
     #
     # tar command tests
diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c
index e440345..7bd6539 100644
--- a/source3/smbd/posix_acls.c
+++ b/source3/smbd/posix_acls.c
@@ -3671,7 +3671,7 @@ NTSTATUS try_chown(files_struct *fsp, uid_t uid, gid_t gid)
 	   a local SID on the users workstation
 	*/
 	if (uid != get_current_uid(fsp->conn)) {
-		return NT_STATUS_ACCESS_DENIED;
+		return NT_STATUS_INVALID_OWNER;
 	}
 
 	become_root();
diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c
index dc0d14d..d4fccb7 100644
--- a/source3/smbd/vfs.c
+++ b/source3/smbd/vfs.c
@@ -858,6 +858,8 @@ const char *vfs_readdirname(connection_struct *conn, void *p,
 int vfs_ChDir(connection_struct *conn, const struct smb_filename *smb_fname)
 {
 	int ret;
+	int saved_errno = 0;
+	struct smb_filename *saved_cwd = NULL;
 
 	if (!LastDir) {
 		LastDir = SMB_STRDUP("");
@@ -872,23 +874,80 @@ int vfs_ChDir(connection_struct *conn, const struct smb_filename *smb_fname)
 		return 0;
 	}
 
+	if (conn->cwd_fname != NULL) {
+		/*
+		 * Save off where we are in case we need to return
+		 * on vfs_GetWd() failure after successful SMB_VFS_CHDIR().
+		 */
+		saved_cwd = cp_smb_filename(conn, conn->cwd_fname);
+		if (saved_cwd == NULL) {
+			return -1;
+		}
+	}
+
 	DEBUG(4,("vfs_ChDir to %s\n", smb_fname->base_name));
 
 	ret = SMB_VFS_CHDIR(conn, smb_fname);
-	if (ret == 0) {
-		/* Global cache. */
-		SAFE_FREE(LastDir);
-		LastDir = SMB_STRDUP(smb_fname->base_name);
-
-		/* conn cache. */
-		TALLOC_FREE(conn->cwd_fname);
-		conn->cwd_fname = vfs_GetWd(conn, conn);
-		if (conn->cwd_fname == NULL) {
-			smb_panic("con->cwd getwd failed\n");
+	if (ret != 0) {
+		saved_errno = errno;
+		TALLOC_FREE(saved_cwd);
+		errno = saved_errno;
+		return -1;
+	}
+
+	/*
+	 * Always replace conn->cwd_fname. We
+	 * don't know if it's been modified by
+	 * VFS modules in the stack.
+	 */
+
+	/* conn cache. */
+	TALLOC_FREE(conn->cwd_fname);
+	conn->cwd_fname = vfs_GetWd(conn, conn);
+	if (conn->cwd_fname == NULL) {
+		/*
+		 * vfs_GetWd() failed.
+		 * We must be able to read cwd.
+		 * Return to original directory
+		 * and return -1.
+		 */
+		saved_errno = errno;
+
+		if (saved_cwd == NULL) {
+			/*
+			 * Failed on the very first chdir()+getwd()
+			 * for this connection. We can't
+			 * continue.
+			 */
+			smb_panic("conn->cwd getwd failed\n");
 			/* NOTREACHED */
 			return -1;
 		}
-		DEBUG(4,("vfs_ChDir got %s\n",conn->cwd_fname->base_name));
+
+		/* Return to the previous $cwd. */
+		ret = SMB_VFS_CHDIR(conn, saved_cwd);
+		if (ret != 0) {
+			smb_panic("conn->cwd getwd failed\n");
+			/* NOTREACHED */
+			return -1;
+		}
+		/* Restore original conn->cwd_fname. */
+		conn->cwd_fname = saved_cwd;
+		errno = saved_errno;
+		/* And fail the chdir(). */
+		return -1;
+	}
+
+	/* vfs_GetWd() succeeded. */
+	/* Replace global cache. */
+	SAFE_FREE(LastDir);
+	LastDir = SMB_STRDUP(smb_fname->base_name);
+
+	DEBUG(4,("vfs_ChDir got %s\n", conn->cwd_fname->base_name));
+
+	TALLOC_FREE(saved_cwd);
+	if (saved_errno != 0) {
+		errno = saved_errno;
 	}
 	return ret;
 }


-- 
Samba Shared Repository



More information about the samba-cvs mailing list