[PATCH] smbd: Fix snapshot query on shares with DFS enabled

Uri Simchoni uri at samba.org
Tue Aug 23 11:45:21 UTC 2016


On 08/22/2016 07:50 PM, Jeremy Allison wrote:
> 
>> Otherwise RB+ me.
> 
> Thanks !
> 

Jeremy,

Now that we have full client shadow-copy functionality in place, I am
extending our test suite to:
- Test both SMB1 and SMB3 (was just SMB1 up to now)
- Test ability to read snapshot files and list directories (was mostly
testing ability to stat snapshot files)

However, as things stand, the directory listing test fails for SMB1
(passes SMB3), so this cannot be pushed yet. I'll look at it later, but
am attaching this in case you want to have a look yourself (and also to
notify that I'm implementing the tests :))

Those test are pretty much complete, but not quite. Gaps are:
- In the case of regex snapshots, they don't test that we get the right
content (ran out of cleverness...)
- Directory tests also just check success/fail, and not that we got the
listing from the right snapshot.

Thanks,
Uri.
-------------- next part --------------
From fcd7dae7ce3ef80d517c5997dbe2250fca73d17b Mon Sep 17 00:00:00 2001
From: Uri Simchoni <uri at samba.org>
Date: Tue, 16 Aug 2016 07:19:04 +0300
Subject: [PATCH 1/4] s2-selftest: run shadow_copy2 test both in NT1 and SMB3
 modes

Signed-off-by: Uri Simchoni <uri at samba.org>
---
 source3/script/tests/test_shadow_copy.sh | 4 ++--
 source3/selftest/tests.py                | 3 ++-
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/source3/script/tests/test_shadow_copy.sh b/source3/script/tests/test_shadow_copy.sh
index 45d9cf1..2fb1ef5 100755
--- a/source3/script/tests/test_shadow_copy.sh
+++ b/source3/script/tests/test_shadow_copy.sh
@@ -5,7 +5,7 @@
 
 if [ $# -lt 7 ]; then
 cat <<EOF
-Usage: test_shadow_copy SERVER SERVER_IP DOMAIN USERNAME PASSWORD WORKDIR SMBCLIENT
+Usage: test_shadow_copy SERVER SERVER_IP DOMAIN USERNAME PASSWORD WORKDIR SMBCLIENT PARAMS
 EOF
 exit 1;
 fi
@@ -18,8 +18,8 @@ PASSWORD=${5}
 WORKDIR=${6}
 SMBCLIENT=${7}
 shift 7
-SMBCLIENT="$VALGRIND ${SMBCLIENT}"
 ADDARGS="$*"
+SMBCLIENT="$VALGRIND ${SMBCLIENT} ${ADDARGS}"
 
 incdir=`dirname $0`/../../../testprogs/blackbox
 . $incdir/subunit.sh
diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py
index 0a0cb08..291aaa9 100755
--- a/source3/selftest/tests.py
+++ b/source3/selftest/tests.py
@@ -187,7 +187,8 @@ for env in ["fileserver"]:
     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])
+    plantestsuite("samba3.blackbox.shadow_copy2 NT1 (%s)" % env, env, [os.path.join(samba3srcdir, "script/tests/test_shadow_copy.sh"), '$SERVER', '$SERVER_IP', '$DOMAIN', '$USERNAME', '$PASSWORD', '$LOCAL_PATH/shadow', smbclient3, '-m', 'NT1'])
+    plantestsuite("samba3.blackbox.shadow_copy2 SMB3 (%s)" % env, env, [os.path.join(samba3srcdir, "script/tests/test_shadow_copy.sh"), '$SERVER', '$SERVER_IP', '$DOMAIN', '$USERNAME', '$PASSWORD', '$LOCAL_PATH/shadow', smbclient3, '-m', 'SMB3'])
     plantestsuite("samba3.blackbox.smbclient.forceuser_validusers (%s)" % env, env, [os.path.join(samba3srcdir, "script/tests/test_forceuser_validusers.sh"), '$SERVER', '$DOMAIN', '$USERNAME', '$PASSWORD', '$LOCAL_PATH', smbclient3])
     plantestsuite("samba3.blackbox.smbget (%s)" % env, env, [os.path.join(samba3srcdir, "script/tests/test_smbget.sh"), '$SERVER', '$SERVER_IP', '$DOMAIN', 'smbget_user', '$PASSWORD', '$LOCAL_PATH/smbget', smbget])
     plantestsuite("samba3.blackbox.netshareenum (%s)" % env, env, [os.path.join(samba3srcdir, "script/tests/test_shareenum.sh"), '$SERVER', '$USERNAME', '$PASSWORD', rpcclient])
-- 
2.5.5


From 0646f8fa8e111763f610b391acc6f6b59b3fea92 Mon Sep 17 00:00:00 2001
From: Uri Simchoni <uri at samba.org>
Date: Tue, 23 Aug 2016 11:33:52 +0300
Subject: [PATCH 2/4] selftest: add content to files created during
 shadow_copy2 test

This will allow reading them and verifying we got the right version

Signed-off-by: Uri Simchoni <uri at samba.org>
---
 source3/script/tests/test_shadow_copy.sh | 26 ++++++++++++++------------
 1 file changed, 14 insertions(+), 12 deletions(-)

diff --git a/source3/script/tests/test_shadow_copy.sh b/source3/script/tests/test_shadow_copy.sh
index 2fb1ef5..a59aae3 100755
--- a/source3/script/tests/test_shadow_copy.sh
+++ b/source3/script/tests/test_shadow_copy.sh
@@ -52,9 +52,11 @@ build_files()
     local prefix
     local version
     local destdir
+    local content
     rootdir=$1
     prefix=$2
     version=$3
+    content=$4
     if [ -n "$prefix" ] ; then
         destdir=$rootdir/$prefix
     else
@@ -66,27 +68,27 @@ build_files()
         #non-snapshot files
         # for non-snapshot version, create legit files
         # so that wide-link checks focus on snapshot files
-        touch $destdir/foo
+        echo "$content" > $destdir/foo
         mkdir -p $destdir/bar
-        touch $destdir/bar/baz
-        touch $destdir/bar/lfoo
-        touch $destdir/bar/letcpasswd
-        touch $destdir/bar/loutside
+        echo "$content" > $destdir/bar/baz
+        echo "$content" > $destdir/bar/lfoo
+        echo "$content" > $destdir/bar/letcpasswd
+        echo "$content" > $destdir/bar/loutside
     elif [ "$version" = "fullsnap" ] ; then
         #snapshot files
-        touch $destdir/foo
+        echo "$content" > $destdir/foo
         mkdir -p $destdir/bar
-        touch $destdir/bar/baz
+        echo "$content" > $destdir/bar/baz
         ln -fs ../foo $destdir/bar/lfoo
         ln -fs /etc/passwd $destdir/bar/letcpasswd
         ln -fs ../../outside $destdir/bar/loutside
-        touch `dirname $destdir`/outside
+        echo "$content" > `dirname $destdir`/outside
     else #subshare snapshot - at bar
-        touch $destdir/baz
+        echo "$content" > $destdir/baz
         ln -fs ../foo $destdir/lfoo
         ln -fs /etc/passwd $destdir/letcpasswd
         ln -fs ../../outside $destdir/loutside
-        touch `dirname $destdir`/../outside
+        echo "$content" > `dirname $destdir`/../outside
     fi
 
 }
@@ -127,7 +129,7 @@ build_snapshots()
     for i in `seq $start $end` ; do
         snapname=${SNAPSHOTS[$i]}
         mkdir $snapdir/$snapname
-        build_files $snapdir/$snapname "$prefix" $version
+        build_files $snapdir/$snapname "$prefix" $version "$snapname"
     done
 }
 
@@ -295,7 +297,7 @@ test_shadow_copy_format()
 }
 
 #build "latest" files
-build_files $WORKDIR/mount base/share "latest"
+build_files $WORKDIR/mount base/share "latest" "latest"
 
 failed=0
 
-- 
2.5.5


From 0bdf2f95a845f3355cca6455eaea5a8369528f0e Mon Sep 17 00:00:00 2001
From: Uri Simchoni <uri at samba.org>
Date: Tue, 23 Aug 2016 14:03:30 +0300
Subject: [PATCH 3/4] selftest: check file readability in shadow_copy2 test

Add tests which verify that a snapshot file is readable
if and only if it its metadata can be retrieved. Also
verify (in most tests) that file is retrieved from the
correct snapshot.

Together with the existing test for number of previous
versions we can stat, this test checks that we can read
those files, and also that we cannot break out of a snapshot
if wide links are not allowed.

Signed-off-by: Uri Simchoni <uri at samba.org>
---
 source3/script/tests/test_shadow_copy.sh | 44 +++++++++++++++++++++++++++-----
 1 file changed, 37 insertions(+), 7 deletions(-)

diff --git a/source3/script/tests/test_shadow_copy.sh b/source3/script/tests/test_shadow_copy.sh
index a59aae3..2b72f06 100755
--- a/source3/script/tests/test_shadow_copy.sh
+++ b/source3/script/tests/test_shadow_copy.sh
@@ -139,18 +139,48 @@ test_count_versions()
     local share
     local path
     local expected_count
+    local skip_content
     local versions
+    local tstamps
+    local tstamp
+    local content
 
     share=$1
     path=$2
     expected_count=$3
+    skip_content=$4
     versions=`$SMBCLIENT -U$USERNAME%$PASSWORD "//$SERVER/$share" -I $SERVER_IP -c "allinfo $path" | grep "^create_time:" | wc -l`
-    if [ "$versions" = "$expected_count" ] ; then
-        true
-    else
+    if [ "$versions" != "$expected_count" ] ; then
         echo "expected $expected_count versions of $path, got $versions"
-        false
+        return 1
     fi
+
+    #readable snapshots
+    tstamps=`$SMBCLIENT -U$USERNAME%$PASSWORD "//$SERVER/$share" -I $SERVER_IP -c "allinfo $path" | awk '/^@GMT-/ {snapshot=$1} /^create_time:/ {printf "%s\n", snapshot}'`
+    for tstamp in $tstamps ; do
+        if ! $SMBCLIENT -U$USERNAME%$PASSWORD "//$SERVER/$share" -I $SERVER_IP -c "get $tstamp\\$path $WORKDIR/foo" ; then
+            echo "Failed getting \\\\$SERVER\\$share\\$tstamp\\$path"
+            return 1
+        fi
+        #also check the content, but not for wide links
+        if [ "x$skip_content" != "x1" ] ; then
+            content=`cat $WORKDIR/foo`
+            if [ "$content" != "$tstamp" ] ; then
+                echo "incorrect content of \\\\$SERVER\\$share\\$tstamp\\$path expected [$tstamp]  got [$content]"
+                return 1
+            fi
+        fi
+    done
+
+    #non-readable snapshots
+    tstamps=`$SMBCLIENT -U$USERNAME%$PASSWORD "//$SERVER/$share" -I $SERVER_IP -c "allinfo $path" | \
+        awk '/^@GMT-/ {if (snapshot!=""){printf "%s\n", snapshot} ; snapshot=$1} /^create_time:/ {snapshot=""} END {if (snapshot!=""){printf "%s\n", snapshot}}'`
+    for tstamp in $tstamps ; do
+        if $SMBCLIENT -U$USERNAME%$PASSWORD "//$SERVER/$share" -I $SERVER_IP -c "get $tstamp\\$path $WORKDIR/foo" ; then
+            echo "Unexpected success getting \\\\$SERVER\\$share\\$tstamp\\$path"
+            return 1
+        fi
+    done
 }
 
 # Test fetching a previous version of a file
@@ -206,11 +236,11 @@ test_shadow_copy_fixed()
         failed=`expr $failed + 1`
 
     testit "$msg - abs symlink outside" \
-        test_count_versions $share bar/letcpasswd $ncopies_blocked || \
+        test_count_versions $share bar/letcpasswd $ncopies_blocked  1 || \
         failed=`expr $failed + 1`
 
     testit "$msg - rel symlink outside" \
-        test_count_versions $share bar/loutside $ncopies_blocked || \
+        test_count_versions $share bar/loutside $ncopies_blocked 1 || \
         failed=`expr $failed + 1`
 }
 
@@ -292,7 +322,7 @@ test_shadow_copy_format()
     build_snapshots $WORKDIR/$where "$prefix" 10 19
 
     testit "$msg - regular file" \
-        test_count_versions $share foo $ncopies_allowed || \
+        test_count_versions $share foo $ncopies_allowed 1 || \
         failed=`expr $failed + 1`
 }
 
-- 
2.5.5


From aac46c7c7ebd64690573f7b29735606bd268c14a Mon Sep 17 00:00:00 2001
From: Uri Simchoni <uri at samba.org>
Date: Tue, 23 Aug 2016 14:29:39 +0300
Subject: [PATCH 4/4] selftest: test listing directories inside snapshots

Verify that directories are also listable.

Signed-off-by: Uri Simchoni <uri at samba.org>
---
 source3/script/tests/test_shadow_copy.sh | 40 +++++++++++++++++++++++++++-----
 1 file changed, 34 insertions(+), 6 deletions(-)

diff --git a/source3/script/tests/test_shadow_copy.sh b/source3/script/tests/test_shadow_copy.sh
index 2b72f06..783e7f32 100755
--- a/source3/script/tests/test_shadow_copy.sh
+++ b/source3/script/tests/test_shadow_copy.sh
@@ -144,6 +144,7 @@ test_count_versions()
     local tstamps
     local tstamp
     local content
+    local is_dir
 
     share=$1
     path=$2
@@ -155,13 +156,28 @@ test_count_versions()
         return 1
     fi
 
+    is_dir=0
+    $SMBCLIENT -U$USERNAME%$PASSWORD "//$SERVER/$share" -I $SERVER_IP -c "allinfo $path" | grep "^attributes:.*D" && is_dir=1
+    if [ $is_dir = 1 ] ; then
+        skip_content=1
+    fi
+
     #readable snapshots
     tstamps=`$SMBCLIENT -U$USERNAME%$PASSWORD "//$SERVER/$share" -I $SERVER_IP -c "allinfo $path" | awk '/^@GMT-/ {snapshot=$1} /^create_time:/ {printf "%s\n", snapshot}'`
     for tstamp in $tstamps ; do
-        if ! $SMBCLIENT -U$USERNAME%$PASSWORD "//$SERVER/$share" -I $SERVER_IP -c "get $tstamp\\$path $WORKDIR/foo" ; then
-            echo "Failed getting \\\\$SERVER\\$share\\$tstamp\\$path"
-            return 1
+        if [ $is_dir = 0 ] ;
+        then
+            if ! $SMBCLIENT -U$USERNAME%$PASSWORD "//$SERVER/$share" -I $SERVER_IP -c "get $tstamp\\$path $WORKDIR/foo" ; then
+                echo "Failed getting \\\\$SERVER\\$share\\$tstamp\\$path"
+                return 1
+            fi
+        else
+            if ! $SMBCLIENT -U$USERNAME%$PASSWORD "//$SERVER/$share" -I $SERVER_IP -c "ls $tstamp\\$path\\*" ; then
+                echo "Failed listing \\\\$SERVER\\$share\\$tstamp\\$path"
+                return 1
+            fi
         fi
+
         #also check the content, but not for wide links
         if [ "x$skip_content" != "x1" ] ; then
             content=`cat $WORKDIR/foo`
@@ -176,9 +192,17 @@ test_count_versions()
     tstamps=`$SMBCLIENT -U$USERNAME%$PASSWORD "//$SERVER/$share" -I $SERVER_IP -c "allinfo $path" | \
         awk '/^@GMT-/ {if (snapshot!=""){printf "%s\n", snapshot} ; snapshot=$1} /^create_time:/ {snapshot=""} END {if (snapshot!=""){printf "%s\n", snapshot}}'`
     for tstamp in $tstamps ; do
-        if $SMBCLIENT -U$USERNAME%$PASSWORD "//$SERVER/$share" -I $SERVER_IP -c "get $tstamp\\$path $WORKDIR/foo" ; then
-            echo "Unexpected success getting \\\\$SERVER\\$share\\$tstamp\\$path"
-            return 1
+        if [ $is_dir = 0 ] ;
+        then
+            if $SMBCLIENT -U$USERNAME%$PASSWORD "//$SERVER/$share" -I $SERVER_IP -c "get $tstamp\\$path $WORKDIR/foo" ; then
+                echo "Unexpected success getting \\\\$SERVER\\$share\\$tstamp\\$path"
+                return 1
+            fi
+        else
+            if $SMBCLIENT -U$USERNAME%$PASSWORD "//$SERVER/$share" -I $SERVER_IP -c "ls $tstamp\\$path\\*" ; then
+                echo "Unexpected success listing \\\\$SERVER\\$share\\$tstamp\\$path"
+                return 1
+            fi
         fi
     done
 }
@@ -242,6 +266,10 @@ test_shadow_copy_fixed()
     testit "$msg - rel symlink outside" \
         test_count_versions $share bar/loutside $ncopies_blocked 1 || \
         failed=`expr $failed + 1`
+
+    testit "$msg - list directory" \
+        test_count_versions $share bar $ncopies_allowed || \
+        failed=`expr $failed + 1`
 }
 
 test_shadow_copy_everywhere()
-- 
2.5.5



More information about the samba-technical mailing list