#!/bin/sh # this runs the file serving tests that are expected to pass with samba3 if [ $# -lt 13 ]; then cat </dev/null 2>&1 if [ $? = 0 ]; then # got a prompt .. fail echo matched interactive prompt in non-interactive mode return 1 fi return 0 } # Test that an interactive smbclient prompts to stdout test_interactive_prompt_stdout() { prompt="smb" tmpfile=$PREFIX/smbclient_interactive_prompt_commands cat >$tmpfile </dev/null 2>&1 if [ $? != 0 ]; then echo failed to match interactive prompt on stdout return 1 fi return 0 } # Test creating a bad symlink and deleting it. test_bad_symlink() { prompt="posix_unlink deleted file /newname" tmpfile=$PREFIX/smbclient_bad_symlinks_commands cat >$tmpfile </dev/null 2>&1 ret=$? if [ $ret != 0 ]; then echo "$out" echo "failed create then delete bad symlink - grep failed with $ret" return 1 fi return 0 } # Test creating a good symlink and deleting it by path. test_good_symlink() { tmpfile=$PREFIX/smbclient.in.$$ slink_name="$LOCAL_PATH/slink" slink_target="$LOCAL_PATH/slink_target" touch $slink_target ln -s $slink_target $slink_name cat >$tmpfile <$tmpfile </dev/null 2>&1 ret=$? if [ $ret != 0 ]; then echo "$out" echo "failed writing into read-only directory - grep failed with $ret" return 1 fi return 0 } # Test sending a message test_message() { tmpfile=$PREFIX/message_in.$$ cat >$tmpfile <$tmpfile </dev/null 2>&1 ret=$? if [ $ret != 0 ]; then echo "$out" echo "failed reading owner-only file - grep failed with $ret" return 1 fi return 0 } # Test accessing an msdfs path. test_msdfs_link() { tmpfile=$PREFIX/smbclient.in.$$ prompt=" msdfs-target " cmd='$SMBCLIENT "$@" -U$USERNAME%$PASSWORD //$SERVER/msdfs-share -I $SERVER_IP $ADDARGS -m $PROTOCOL -c dir 2>&1' out=$(eval $cmd) ret=$? if [ $ret != 0 ]; then echo "$out" echo "failed listing msfds-share\ with error $ret" return 1 fi cat >$tmpfile </dev/null 2>&1 ret=$? if [ $ret != 0 ]; then echo "$out" echo "failed listing \\msdfs-src1 - grep failed with $ret" return 1 fi cat >$tmpfile </dev/null 2>&1 ret=$? if [ $ret != 0 ]; then echo "$out" echo "failed listing \\deeppath\\msdfs-src2 - grep failed with $ret" return 1 fi return 0 } # Test recursive listing across msdfs links test_msdfs_recursive_dir() { tmpfile=$PREFIX/smbclient.in.$$ cat >$tmpfile < /dev/null 2>&1 ret="$?" if [ "$ret" -ne 0 ]; then echo "$out" echo "Listing \\msdfs-share recursively did not properly end in symlink recursion" fi return 0 } # Test doing a normal file rename on an msdfs path. test_msdfs_rename() { tmpfile="$PREFIX/smbclient.in.$$" filename_src="src.$$" filename_dst="dest.$$" filename_src_path="$PREFIX/$filename_src" rm -f "$filename_src_path" touch "$filename_src_path" # # Use both non-force and force rename to # ensure we test both codepaths inside libsmb. # cat >$tmpfile </dev/null 2>&1 ret="$?" if [ "$ret" -eq 0 ]; then echo "$out" echo "renaming $filename_src $filename_dst got NT_STATUS_ error" return 1 fi return 0 } # Test doing a normal file hardlink on an msdfs path. test_msdfs_hardlink() { tmpfile="$PREFIX/smbclient.in.$$" filename_src="src.$$" filename_dst="dest.$$" filename_src_path="$PREFIX/$filename_src" rm -f "$filename_src_path" touch "$filename_src_path" cat >$tmpfile </dev/null 2>&1 ret="$?" if [ "$ret" -eq 0 ]; then echo "$out" echo "hardlink $filename_src $filename_dst got NT_STATUS_ error" return 1 fi return 0 } test_msdfs_del() { tmpfile="$PREFIX/smbclient.in.$$" filename_src="src.$$" filename_src_path="$PREFIX/$filename_src" rm -f "$filename_src_path" touch "$filename_src_path" cat > $tmpfile </dev/null 2>&1 ret="$?" if [ "$ret" -eq 0 ] ; then echo "$out" echo "del $filename_src NT_STATUS_ error" return 1 fi return 0 } test_msdfs_deltree() { tmpfile="$PREFIX/smbclient.in.$$" dirname_src="foodir.$$" filename_src="src.$$" filename_src_path="$PREFIX/$filename_src" dirname_src_path="$PREFIX/$dirname" rm -f "$filename_src_path" touch "$filename_src_path" cat > $tmpfile </dev/null 2>&1 ret="$?" if [ "$ret" -eq 0 ] ; then echo "$out" echo "deltree $dirname_src NT_STATUS_ error" return 1 fi return 0 } # Archive bits are correctly set on file/dir creation and rename. test_rename_archive_bit() { prompt_file="attributes: A (20)" prompt_dir="attributes: D (10)" tmpfile="$PREFIX/smbclient.in.$$" filename="foo.$$" filename_ren="bar.$$" dirname="foodir.$$" dirname_ren="bardir.$$" filename_path="$PREFIX/$filename" local_name1="$LOCAL_PATH/$filename" local_name2="$LOCAL_PATH/$filename_ren" local_dir_name1="$LOCAL_PATH/$dirname" local_dir_name2="$LOCAL_PATH/$dirname_ren" rm -f $filename_path rm -f $local_name1 rm -f $local_name2 # Create a new file, ensure it has 'A' attributes. touch $filename_path cat >$tmpfile </dev/null 2>&1 ret=$? rm -f $filename_path rm -f $local_name1 rm -f $local_name2 if [ $ret != 0 ]; then echo "$out" echo "Attributes incorrect on new file $ret" return 1 fi # Now check if we remove 'A' and rename, the A comes back. touch $filename_path cat >$tmpfile </dev/null 2>&1 ret=$? rm -f $filename_path rm -f $local_name1 rm -f $local_name2 if [ $ret != 0 ]; then echo "$out" echo "Attributes incorrect on renamed file $ret" return 1 fi rm -rf $local_dir_name1 rm -rf $local_dir_name2 # Create a new directory, ensure it has 'D' but not 'A' attributes. cat >$tmpfile </dev/null 2>&1 ret=$? rm -rf $local_dir_name1 rm -rf $local_dir_name2 if [ $ret != 0 ]; then echo "$out" echo "Attributes incorrect on new directory $ret" return 1 fi # Now check if we rename, we still only have 'D' attributes cat >$tmpfile </dev/null 2>&1 ret=$? rm -f $local_name1 rm -f $local_name2 if [ $ret != 0 ]; then echo "$out" echo "Attributes incorrect on renamed directory $ret" return 1 fi return 0 } # Test authenticating using the winbind ccache test_ccache_access() { $WBINFO --ccache-save="${USERNAME}%${PASSWORD}" ret=$? if [ $ret != 0 ]; then echo "wbinfo failed to store creds in cache (user='${USERNAME}', pass='${PASSWORD}')" return 1 fi $SMBCLIENT //$SERVER_IP/tmp --use-winbind-ccache -U "${USERNAME}" $ADDARGS -c quit 2>&1 ret=$? if [ $ret != 0 ]; then echo "smbclient failed to use cached credentials" return 1 fi $WBINFO --ccache-save="${USERNAME}%GarBage" ret=$? if [ $ret != 0 ]; then echo "wbinfo failed to store creds in cache (user='${USERNAME}', pass='GarBage')" return 1 fi $SMBCLIENT //$SERVER_IP/tmp --use-winbind-ccache -U "${USERNAME}" $ADDARGS -c quit 2>&1 ret=$? if [ $ret -eq 0 ]; then echo "smbclient succeeded with wrong cached credentials" return 1 fi $WBINFO --logoff } # Test authenticating using the winbind ccache test_auth_file() { tmpfile=$PREFIX/smbclient.in.$$ cat >$tmpfile <&1 ret=$? rm $tmpfile if [ $ret != 0 ]; then echo "smbclient failed to use auth file" return 1 fi cat >$tmpfile <&1 ret=$? rm $tmpfile if [ $ret -eq 0 ]; then echo "smbclient succeeded with wrong auth file credentials" return 1 fi } # Test doing a directory listing with backup privilege. test_backup_privilege_list() { tmpfile=$PREFIX/smbclient_backup_privilege_list # selftest uses the forward slash as a separator, but "net sam rights # grant" requires the backslash separator USER_TMP=$(printf '%s' "$USERNAME" | tr '/' '\\') # If we don't have a DOMAIN component to the username, add it. printf '%s' "$USER_TMP" | grep '\\' 2>&1 ret=$? if [ $ret != 0 ]; then priv_username="$DOMAIN\\$USER_TMP" else priv_username="$USER_TMP" fi $NET sam rights grant $priv_username SeBackupPrivilege 2>&1 ret=$? if [ $ret != 0 ]; then echo "Failed to add SeBackupPrivilege to user $priv_username - $ret" return 1 fi cat >$tmpfile <&1 ret=$? if [ $ret != 0 ]; then echo "failed to remove SeBackupPrivilege from user $priv_username - $ret" return 1 fi } # Test accessing an share with bad names (won't convert). test_bad_names() { # First with SMB1 if [ $PROTOCOL = "NT1" ]; then cmd='CLI_FORCE_INTERACTIVE=yes $SMBCLIENT "$@" -U$USERNAME%$PASSWORD //$SERVER/badname-tmp -I $SERVER_IP $ADDARGS -m$PROTOCOL -c ls 2>&1' eval echo "$cmd" out=$(eval $cmd) ret=$? if [ $ret != 0 ]; then echo "$out" echo "failed accessing badname-tmp (SMB1) with error $ret" return 1 fi echo "$out" | wc -l 2>&1 | grep 5 ret=$? if [ $ret != 0 ]; then echo "$out" echo "failed listing \\badname-tmp - grep of number of lines (1) failed with $ret" return 1 fi echo "$out" | grep '^ \. *D' ret=$? if [ $ret != 0 ]; then echo "$out" echo "failed listing \\badname-tmp - grep (1) failed with $ret" return 1 fi echo "$out" | grep '^ \.\. *D' ret=$? if [ $ret != 0 ]; then echo "$out" echo "failed listing \\badname-tmp - grep (2) failed with $ret" return 1 fi echo "$out" | grep '^ blank.txt *N' ret=$? if [ $ret != 0 ]; then echo "$out" echo "failed listing \\badname-tmp - grep (3) failed with $ret" return 1 fi echo "$out" | grep '^ *$' ret=$? if [ $ret != 0 ]; then echo "$out" echo "failed listing \\badname-tmp - grep (4) failed with $ret" return 1 fi echo "$out" | grep 'blocks of size.*blocks available' ret=$? if [ $ret != 0 ]; then echo "$out" echo "failed listing \\badname-tmp - grep (5) failed with $ret" return 1 fi fi if [ $PROTOCOL = "SMB3" ]; then # Now check again with -mSMB3 cmd='CLI_FORCE_INTERACTIVE=yes $SMBCLIENT "$@" -U$USERNAME%$PASSWORD //$SERVER/badname-tmp -I $SERVER_IP $ADDARGS -m$PROTOCOL -c ls 2>&1' eval echo "$cmd" out=$(eval $cmd) ret=$? if [ $ret != 0 ]; then echo "$out" echo "failed accessing badname-tmp (SMB3) with error $ret" return 1 fi echo "$out" | wc -l 2>&1 | grep 5 ret=$? if [ $ret != 0 ]; then echo "$out" echo "failed listing \\badname-tmp - SMB3 grep of number of lines (1) failed with $ret" return 1 fi echo "$out" | grep '^ \. *D' ret=$? if [ $ret != 0 ]; then echo "$out" echo "failed listing \\badname-tmp - SMB3 grep (1) failed with $ret" return 1 fi echo "$out" | grep '^ \.\. *D' ret=$? if [ $ret != 0 ]; then echo "$out" echo "failed listing \\badname-tmp - SMB3 grep (2) failed with $ret" return 1 fi echo "$out" | grep '^ blank.txt *N' ret=$? if [ $ret != 0 ]; then echo "$out" echo "failed listing \\badname-tmp - SMB3 grep (3) failed with $ret" return 1 fi echo "$out" | grep '^ *$' ret=$? if [ $ret != 0 ]; then echo "$out" echo "failed listing \\badname-tmp - SMB3 grep (4) failed with $ret" return 1 fi echo "$out" | grep 'blocks of size.*blocks available' ret=$? if [ $ret != 0 ]; then echo "$out" echo "failed listing \\badname-tmp - SMB3 grep (5) failed with $ret" return 1 fi fi } # Test accessing an share with a name that must be mangled - with acl_xattrs. # We know foo:bar gets mangled to FF4GBY~Q with the default name-mangling algorithm (hash2). test_mangled_names() { tmpfile=$PREFIX/smbclient_interactive_prompt_commands cat >$tmpfile <$tmpfile <$tmpfile <$tmpfile <$tmpfile <$tmpfile <$tmpfile <$PREFIX/$local_nosymlink_target_file local_foobar_target_file="testfile" echo "$share_target_file" >$PREFIX/$local_foobar_target_file tmpfile=$PREFIX/smbclient_interactive_prompt_commands cat >$tmpfile <$tmpfile <$tmpfile <$tmpfile <$tmpfile <$tmpfile <$tmpfile <$tmpfile <$tmpfile <$tmpfile <$tmpfile <$tmpfile <$tmpfile <$tmpfile <$tmpfile <$tmpfile <$tmpfile <$tmpfile <$tmpfile </dev/null 2>&1 if [ $? != 0 ]; then # didn't get output to stdout echo "expected output was NOT output to stdout" return 1 fi # this time execute ls but redirect stdout alone to /dev/null cmd='$SMBCLIENT -E "$@" -U$USERNAME%$PASSWORD //$SERVER/tmp -c "ls" 2>&1 > /dev/null' eval echo "$cmd" out=$(eval $cmd) if [ $? != 0 ]; then echo "$out" echo "command failed" return 1 fi # test smbclient 'ls' command output went to stderr echo "$out" | grep "blocks available" >/dev/null 2>&1 if [ $? != 0 ]; then # didn't get output to stderr echo "expected output was NOT output to stderr" return 1 fi return 0 } # # LOGDIR_PREFIX=test_smbclient_s3 # possibly remove old logdirs: for OLDDIR in $(find ${PREFIX} -type d -name "${LOGDIR_PREFIX}_*"); do echo "removing old directory ${OLDDIR}" rm -rf ${OLDDIR} done LOGDIR=$(mktemp -d ${PREFIX}/${LOGDIR_PREFIX}_XXXXXX) testit "smbclient -L $SERVER_IP" $SMBCLIENT -L $SERVER_IP -N -p 139 ${RAWARGS} || failed=$(expr $failed + 1) testit "smbclient -L $SERVER -I $SERVER_IP" $SMBCLIENT -L $SERVER -I $SERVER_IP -N -p 139 ${RAWARGS} -c quit || failed=$(expr $failed + 1) testit "noninteractive smbclient does not prompt" \ test_noninteractive_no_prompt || failed=$(expr $failed + 1) testit "noninteractive smbclient -l does not prompt" \ test_noninteractive_no_prompt -l $LOGDIR || failed=$(expr $failed + 1) testit "smbclient output goes to stderr when -E is passed" \ test_smbclient_minus_e_stderr || failed=$(expr $failed + 1) testit "interactive smbclient prompts on stdout" \ test_interactive_prompt_stdout || failed=$(expr $failed + 1) testit "interactive smbclient -l prompts on stdout" \ test_interactive_prompt_stdout -l $LOGDIR || failed=$(expr $failed + 1) testit "creating a bad symlink and deleting it" \ test_bad_symlink || failed=$(expr $failed + 1) testit "creating a good symlink and deleting it by path" \ test_good_symlink || failed=$(expr $failed + 1) testit "writing into a read-only directory fails" \ test_read_only_dir ro-tmp || failed=$(expr $failed + 1) testit "writing into a read-only share fails" \ test_read_only_dir valid-users-tmp || failed=$(expr $failed + 1) testit "Reading a owner-only file fails" \ test_owner_only_file || failed=$(expr $failed + 1) testit "Accessing an MS-DFS link" \ test_msdfs_link || failed=$(expr $failed + 1) testit "Recursive ls across MS-DFS links" \ test_msdfs_recursive_dir || failed=$(expr $failed + 1) testit "Rename on MS-DFS share" \ test_msdfs_rename || failed=$(expr $failed + 1) testit "Hardlink on MS-DFS share" \ test_msdfs_hardlink || failed=$(expr $failed + 1) testit "del on MS-DFS share" \ test_msdfs_del || \ failed=`expr $failed + 1` testit "deltree on MS-DFS share" \ test_msdfs_deltree || \ failed=`expr $failed + 1` testit "Ensure archive bit is set correctly on file/dir rename" \ test_rename_archive_bit || failed=$(expr $failed + 1) testit "ccache access works for smbclient" \ test_ccache_access || failed=$(expr $failed + 1) testit "sending a message to the remote server" \ test_message || failed=$(expr $failed + 1) testit "using an authentication file" \ test_auth_file || failed=$(expr $failed + 1) testit "list with backup privilege" \ test_backup_privilege_list || failed=$(expr $failed + 1) testit "list a share with bad names (won't convert)" \ test_bad_names || failed=$(expr $failed + 1) testit "list a share with a mangled name + acl_xattr object" \ test_mangled_names || failed=$(expr $failed + 1) testit "server-side file copy" \ test_scopy || failed=$(expr $failed + 1) testit "creating a :stream at root of share" \ test_toplevel_stream || failed=$(expr $failed + 1) testit "Ensure widelinks are restricted" \ test_widelinks || failed=$(expr $failed + 1) testit "streams_depot can delete correctly" \ test_streams_depot_delete || failed=$(expr $failed + 1) testit "stream_xattr attributes" \ test_stream_directory_xattr || failed=$(expr $failed + 1) testit "follow symlinks = no" \ test_nosymlinks || failed=$(expr $failed + 1) testit "follow local symlinks" \ test_local_symlinks || failed=$(expr $failed + 1) testit "noperm share regression" \ test_noperm_share_regression || failed=$(expr $failed + 1) testit "smbclient deltree command" \ test_deltree || failed=$(expr $failed + 1) testit "server os message" \ test_server_os_message || failed=$(expr $failed + 1) testit "test server quiet message" \ test_server_quiet_message || failed=$(expr $failed + 1) testit "setmode test" \ test_setmode || failed=$(expr $failed + 1) testit "utimes" \ test_utimes || failed=$(expr $failed + 1) testit "rename_dotdot" \ test_rename_dotdot || failed=$(expr $failed + 1) testit "volume" \ test_volume || failed=$(expr $failed + 1) testit "rm -rf $LOGDIR" \ rm -rf $LOGDIR || failed=$(expr $failed + 1) testit "delete a non empty directory" \ test_del_nedir || failed=$(expr $failed + 1) testit "valid users" \ test_valid_users || failed=$(expr $failed + 1) testok $0 $failed