diff options
Diffstat (limited to '')
-rw-r--r-- | source4/selftest/win/README | 72 | ||||
-rw-r--r-- | source4/selftest/win/VMHost.pm | 359 | ||||
-rw-r--r-- | source4/selftest/win/common.exp | 521 | ||||
-rw-r--r-- | source4/selftest/win/test_win.conf | 83 | ||||
-rw-r--r-- | source4/selftest/win/vm_get_ip.pl | 48 | ||||
-rw-r--r-- | source4/selftest/win/vm_load_snapshot.pl | 46 | ||||
-rwxr-xr-x | source4/selftest/win/wintest_2k3_dc.sh | 120 | ||||
-rwxr-xr-x | source4/selftest/win/wintest_base.sh | 68 | ||||
-rw-r--r-- | source4/selftest/win/wintest_client.exp | 95 | ||||
-rwxr-xr-x | source4/selftest/win/wintest_client.sh | 26 | ||||
-rwxr-xr-x | source4/selftest/win/wintest_functions.sh | 54 | ||||
-rwxr-xr-x | source4/selftest/win/wintest_net.sh | 63 | ||||
-rwxr-xr-x | source4/selftest/win/wintest_raw.sh | 69 | ||||
-rw-r--r-- | source4/selftest/win/wintest_remove.exp | 71 | ||||
-rwxr-xr-x | source4/selftest/win/wintest_rpc.sh | 67 | ||||
-rw-r--r-- | source4/selftest/win/wintest_setup.exp | 104 |
16 files changed, 1866 insertions, 0 deletions
diff --git a/source4/selftest/win/README b/source4/selftest/win/README new file mode 100644 index 0000000..f6e716c --- /dev/null +++ b/source4/selftest/win/README @@ -0,0 +1,72 @@ +This framework uses a VMware Server hosted Windows guest VM to test the +behaviour of Windows -> Samba and Samba -> Windows interactions. To setup a +Windows host for testing, vm_setup.tar.gz contain some scripts which create +an administrative user account, and enable and start the installed telnet +service on the Windows host. Optionally, the hostname and workgroup name can +also be set. vm_setup.tar.gz is currently located in the SOC/bnh branch of +Samba's SVN repository. + +PREREQUISITES + +To use these scripts, VMware Server needs to be running with a Windows guest +VM installed, IP addressed, and VMware tools needs to be installed and running +on the guest VM. The Windows OS I used to test with was Windows Server 2003, +but I think this should work with any version of Windows that has the +Microsoft telnet service installed. The VMware Server versions I used for +testing was 1.0.0 build-27828, and 1.0.0 build-28343. + +PLEASE NOTE: Due to problems with my original revert_snapshot() code, the initial +setup now requires that the VM configuration setting 'When Powering Off' is +manually set to 'Revert to snapshot' (snapshot.action="autoRevert" in the +guest's .vmx file). This should not be a permanent change, but the original +revert_snapshot() code I wrote no longer works and i'm not sure why. + +On the machine that these scripts are running on (this need not be the same +machine as the VMware host), the VMware perl scripting api needs to be +installed, as well as the vix-perl api. These come with the VMware Server +console package. + +After unzipping this file, the libraries are installed by extracting the +VMware-vix-e.x.p-<revision number>.tar.gz and +VMware-VmPerlAPI-e.x.p-<revision number>.tar.gz archives, and running the +vmware-install.pl scripts inside their respective directories. + +On Slackware 10.2, I encountered a problem in that when I tried to use the vix +api libraries, I would get the following error: + +SSLLoadSharedLibrary: Failed to load library /<client program directory>/libcrypto.so.0.9.7:/<client program directory>/libcrypto.so.0.9.7: cannot open a shared object file: No such file or directory. + +The fix found on the VMware knowledge base (search http://kb.vmware.com for +Doc ID: 1837104) states that it's a known problem with the scripting libraries, +and can be resolved by installing VMware Server on the host, which properly +sets up the SSL module loader. This is what I would suggest if you encounter +this, as it solved the problem for me (I don't have VMware Server actually +running on that host though). + +INSTALLATION + +To use these scripts, modify initial_setup.conf to match your environment. The +GUEST_HOSTNAME, GUEST_WORKGROUP, HOST_SERVER_NAME, HOST_SERVER_PORT, +HOST_USERNAME, and HOST_PASSWORD variables are optional, and are commented out +in this release. + +Running initial_setup.sh will: +* Get the IP address of the Windows guest VM. +* Take a snapshot of the pristine Windows guest. +* Copy the windows scripts from the windows-scripts directory on the unix host + to the directory on the Windows guest specified by the + GUEST_SCRIPT_PATH option. This path will be created on the guest if + it does not already exist. +* Execute win_setup.wsf on the Windows guest in order to create the + administrator account specified by GUEST_USERNAME and GUEST_PASSWORD, + enable and start the telnet service, and set the GUEST_HOSTNAME and + GUEST_WORKGROUP if configured. +* If these operations are successful so far, another snapshot is taken at this + point. This is the snapshot which is restored if the tests encounter + problems they are unable to recover from. + +These operations leave the Windows guest in a state such that it can be +remotely administered with telnet. Specifically, this will allow us to use +'make wintest' in Samba 4 to perform smbtorture tests against a Windows host, +and perform tests from a Windows client to a Samba server. + diff --git a/source4/selftest/win/VMHost.pm b/source4/selftest/win/VMHost.pm new file mode 100644 index 0000000..37d721e --- /dev/null +++ b/source4/selftest/win/VMHost.pm @@ -0,0 +1,359 @@ +#!/usr/bin/perl -w + +# A perl object to provide a simple, unified method of handling some +# VMware Server VM management functions using the perl and VIX API's. +# Copyright Brad Henry <brad@samba.org> 2006 +# Released under the GNU GPL version 3 or later. + +# VMware Perl API +use VMware::VmPerl; +use VMware::VmPerl::VM; +use VMware::VmPerl::ConnectParams; + +# VMware C bindings +use VMware::Vix::Simple; +use VMware::Vix::API::Constants; + +# Create a class to abstract from the Vix and VMPerl APIs. +{ package VMHost; + my $perl_vm = VMware::VmPerl::VM::new(); + my $perl_vm_credentials; + my $vix_vm; + my $vix_vm_host; + + my $err_code = 0; + my $err_str = ""; + + my $hostname; + my $port; + my $username; + my $password; + my $vm_cfg_path; + my $guest_admin_username; + my $guest_admin_password; + + sub error { + my $old_err_code = $err_code; + my $old_err_str = $err_str; + $err_code = 0; + $err_str = ""; + return ($old_err_code, $old_err_str); + } + + # Power on the guest if it isn't already running. + # Returns 0 when the guest is already running, and + # if not, it waits until it is started. + sub start_guest { + my $vm_power_state = $perl_vm->get_execution_state(); + if (!defined($vm_power_state)) { + ($err_code, $err_str) = $perl_vm->get_last_error(); + return ($err_code); + } + if ($vm_power_state == VMware::VmPerl::VM_EXECUTION_STATE_OFF + || $vm_power_state == + VMware::VmPerl::VM_EXECUTION_STATE_SUSPENDED) + { + if (!$perl_vm->start()) { + ($err_code, $err_str) = + $perl_vm->get_last_error(); + return ($err_code); + } + while ($perl_vm->get_tools_last_active() == 0) { + sleep(60); + } + } + return ($err_code); + } + + sub host_connect { + # When called as a method, the first parameter passed is the + # name of the method. Called locally, this function will lose + # the first parameter. + shift @_; + ($hostname, $port, $username, $password, $vm_cfg_path, + $guest_admin_username, $guest_admin_password) = @_; + + # Connect to host using vmperl api. + $perl_vm_credentials = + VMware::VmPerl::ConnectParams::new($hostname, $port, + $username, $password); + if (!$perl_vm->connect($perl_vm_credentials, $vm_cfg_path)) { + ($err_code, $err_str) = $perl_vm->get_last_error(); + undef $perl_vm; + return ($err_code); + } + + # Connect to host using vix api. + ($err_code, $vix_vm_host) = + VMware::Vix::Simple::HostConnect( + VMware::Vix::Simple::VIX_API_VERSION, + VMware::Vix::Simple::VIX_SERVICEPROVIDER_VMWARE_SERVER, + $hostname, $port, $username, $password, + 0, VMware::Vix::Simple::VIX_INVALID_HANDLE); + if ($err_code != VMware::Vix::Simple::VIX_OK) { + $err_str = + VMware::Vix::Simple::GetErrorText($err_code); + undef $perl_vm; + undef $vix_vm; + undef $vix_vm_host; + return ($err_code); + } + + # Power on our guest os if it isn't already running. + $err_code = start_guest(); + if ($err_code != 0) { + my $old_err_str = $err_str; + $err_str = "Starting guest power after connect " . + "failed: " . $old_err_str; + undef $perl_vm; + undef $vix_vm; + undef $vix_vm_host; + return ($err_code); + } + + # Open VM. + ($err_code, $vix_vm) = + VMware::Vix::Simple::VMOpen($vix_vm_host, $vm_cfg_path); + if ($err_code != VMware::Vix::Simple::VIX_OK) { + $err_str = + VMware::Vix::Simple::GetErrorText($err_code); + undef $perl_vm; + undef $vix_vm; + undef $vix_vm_host; + return ($err_code); + } + + # Login to $vix_vm guest OS. + $err_code = VMware::Vix::Simple::VMLoginInGuest($vix_vm, + $guest_admin_username, $guest_admin_password, + 0); + if ($err_code != VMware::Vix::Simple::VIX_OK) { + $err_str = + VMware::Vix::Simple::GetErrorText($err_code); + undef $perl_vm; + undef $vix_vm; + undef $vix_vm_host; + return ($err_code); + } + return ($err_code); + } + + sub host_disconnect { + undef $perl_vm; + + $perl_vm = VMware::VmPerl::VM::new(); + if (!$perl_vm) { + $err_code = 1; + $err_str = "Error creating new VmPerl object"; + } + + undef $vix_vm; + VMware::Vix::Simple::HostDisconnect($vix_vm_host); + VMware::Vix::Simple::ReleaseHandle($vix_vm_host); + return ($err_code); + } + + sub host_reconnect { + $err_code = host_disconnect(); + if ($err_code != 0) { + my $old_err_str = $err_str; + $err_str = "Disconnecting from host failed: " . + $old_err_str; + return ($err_code); + } + + $err_code = host_connect(NULL, $hostname, $port, $username, + $password, $vm_cfg_path, $guest_admin_username, + $guest_admin_password); + if ($err_code != 0) { + my $old_err_str = $err_str; + $err_str = "Re-connecting to host failed: " . + $old_err_str; + return ($err_code); + } + return ($err_code); + } + + sub create_snapshot { + my $snapshot; + + ($err_code, $snapshot) = + VMware::Vix::Simple::VMCreateSnapshot($vix_vm, + "Snapshot", "Created by vm_setup.pl", 0, + VMware::Vix::Simple::VIX_INVALID_HANDLE); + + VMware::Vix::Simple::ReleaseHandle($snapshot); + + if ($err_code != VMware::Vix::Simple::VIX_OK) { + $err_str = + VMware::Vix::Simple::GetErrorText($err_code); + return $err_code; + } + + $err_code = host_reconnect(); + if ($err_code != 0) { + my $old_err_str = $err_str; + $err_str = "Reconnecting to host after creating " . + "snapshot: " . $old_err_str; + return ($err_code); + } + return ($err_code); + } + + sub revert_snapshot { + # Because of problems with VMRevertToSnapshot(), we have to + # rely on the guest having set 'Revert to Snapshot' following + # a power-off event. + $err_code = VMware::Vix::Simple::VMPowerOff($vix_vm, 0); + if ($err_code != VMware::Vix::Simple::VIX_OK) { + $err_str = + VMware::Vix::Simple::GetErrorText($err_code); + return $err_code; + } + + # host_reconnect() will power-on a guest in a non-running state. + $err_code = host_reconnect(); + if ($err_code != 0) { + my $old_err_str = $err_str; + $err_str = "Reconnecting to host after reverting " . + "snapshot: " . $old_err_str; + return ($err_code); + } + return ($err_code); + } + + # $dest_path must exist. It doesn't get created. + sub copy_files_to_guest { + shift @_; + my (%files) = @_; + + my $src_file; + my $dest_file; + + foreach $src_file (keys(%files)) { + $dest_file = $files{$src_file}; + $err_code = + VMware::Vix::Simple::VMCopyFileFromHostToGuest( + $vix_vm, $src_file, $dest_file, 0, + VMware::Vix::Simple::VIX_INVALID_HANDLE); + if ($err_code != VMware::Vix::Simple::VIX_OK) { + $err_str = "Copying $src_file: " . + VMware::Vix::Simple::GetErrorText( + $err_code); + return $err_code; + } + } + return $err_code; + } + + sub copy_to_guest { + # Read parameters $src_path, $dest_path. + shift @_; + my ($src_path, $dest_dir) = @_; + + my $len = length($dest_dir); + my $idx = rindex($dest_dir, '\\'); + if ($idx != ($len - 1)) { + $err_code = -1; + $err_str = "Destination $dest_dir must be a " . + "directory path"; + return ($err_code); + } + + # Create the directory $dest_path on the guest VM filesystem. + my $cmd = "cmd.exe "; + my $cmd_args = "/C MKDIR " . $dest_dir; + $err_code = run_on_guest(NULL, $cmd, $cmd_args); + if ( $err_code != 0) { + my $old_err_str = $err_str; + $err_str = "Creating directory $dest_dir on host: " . + $old_err_str; + return ($err_code); + } + + # If $src_filepath specifies a file, create it in $dest_path + # and keep the same name. + # If $src_path is a directory, create the files it contains in + # $dest_path, keeping the same names. + $len = length($src_path); + my %files; + $idx = rindex($src_path, '/'); + if ($idx == ($len - 1)) { + # $src_path is a directory. + if (!opendir (DIR_HANDLE, $src_path)) { + $err_code = -1; + $err_str = "Error opening directory $src_path"; + return $err_code; + } + + foreach $file (readdir DIR_HANDLE) { + my $src_file = $src_path . $file; + + if (!opendir(DIR_HANDLE2, $src_file)) { + # We aren't interested in subdirs. + my $dest_path = $dest_dir . $file; + $files{$src_file} = $dest_path; + } else { + closedir(DIR_HANDLE2); + } + } + } else { + # Strip if preceding path from $src_path. + my $src_file = substr($src_path, ($idx + 1), $len); + my $dest_path = $dest_dir . $src_file; + + # Add $src_path => $dest_path to %files. + $files{$src_path} = $dest_path; + } + + $err_code = copy_files_to_guest(NULL, %files); + if ($err_code != 0) { + my $old_err_str = $err_str; + $err_str = "Copying files to host after " . + "populating %files: " . $old_err_str; + return ($err_code); + } + return ($err_code); + } + + sub run_on_guest { + # Read parameters $cmd, $cmd_args. + shift @_; + my ($cmd, $cmd_args) = @_; + + $err_code = VMware::Vix::Simple::VMRunProgramInGuest($vix_vm, + $cmd, $cmd_args, 0, + VMware::Vix::Simple::VIX_INVALID_HANDLE); + if ($err_code != VMware::Vix::Simple::VIX_OK) { + $err_str = VMware::Vix::Simple::GetErrorText( + $err_code); + return ($err_code); + } + + return ($err_code); + } + + sub get_guest_ip { + my $guest_ip = $perl_vm->get_guest_info('ip'); + + if (!defined($guest_ip)) { + ($err_code, $err_str) = $perl_vm->get_last_error(); + return NULL; + } + + if (!($guest_ip)) { + $err_code = 1; + $err_str = "Guest did not set the 'ip' variable"; + return NULL; + } + return $guest_ip; + } + + sub DESTROY { + host_disconnect(); + undef $perl_vm; + undef $vix_vm_host; + } +} + +return TRUE; diff --git a/source4/selftest/win/common.exp b/source4/selftest/win/common.exp new file mode 100644 index 0000000..93d24a6 --- /dev/null +++ b/source4/selftest/win/common.exp @@ -0,0 +1,521 @@ +# A library of commonly used functions written in expect. +# Copyright Brad Henry <brad@samba.org> 2006 +# Released under the GNU GPL version 3 or later. + +# This function maps a drive letter to a share point. +proc map_share { remote_prompt share_drive sharepoint username domain password } { + set default_err_str "Unknown error in function map_share" + set err_str $default_err_str + + set cmd "net use $share_drive $sharepoint $password /USER:$username@$domain\r\n" + send $cmd + + expect { + "The command completed successfully." { + expect_prompt $remote_prompt + set err_str "OK" + } \ + "The local device name is already in use." { + expect_prompt $remote_prompt + set err_str "The device name $share_drive is already in use" + } \ + "The network name cannot be found." { + expect_prompt $remote_prompt + set err_str "Sharepoint $sharepoint could not be found" + } \ + timeout { + set err_str "Function map_share timed out while mapping $share_drive to $sharepoint" + } + } + return $err_str +} + +# This function unmaps a drive letter from a share point. +proc unmap_share { remote_prompt share_drive } { + set default_err_str "Unknown error in function unmap_share" + set err_str $default_err_str + + set cmd "net use $share_drive /DELETE\r\n" + send $cmd + + expect { + "was deleted successfully." { + expect_prompt $remote_prompt + set err_str "OK" + } \ + "NET HELPMSG 2250" { + expect_prompt $remote_prompt + set err_str "The network connection could not be found while unmapping $share_drive" + } \ + timeout { + set err_str "Function unmap_share timed out while unmapping $share_drive" + } + } + return $err_str +} + +# This function uses xcopy to copy a text file from one location on the +# remote windows host to another. +proc xcopy_file { remote_prompt in_filename out_filename xcopy_options } { + set default_err_str "Unknown error in function xcopy_file" + set err_str $default_err_str + + set cmd "xcopy $in_filename $out_filename $xcopy_options\r\n" + send $cmd + + expect { + "(F = file, D = directory)? " { + set cmd "F\r\n" + send $cmd + expect { + "1 File(s) copied\r\n\r\n" { + expect_prompt $remote_prompt + set err_str "OK" + } \ + "0 File(s) copied\r\n\r\n" { + expect_prompt $remote_prompt + set err_str $default_err_str + } \ + timeout { + set err_str "Function xcopy_file has timed out while copying $in_filename" + } + } + } \ + "1 File(s) copied\r\n\r\n" { + expect_prompt $remote_prompt + set err_str "OK" + } \ + "0 File(s) copied\r\n\r\n" { + expect_prompt $remote_prompt + set err_str $default_err_str + } \ + timeout { + set err_str "Function xcopy_file timed out while copying $in_filename" + } + } + return $err_str +} + +# This function creates a temporary file on the remote windows host. +# The file contents are populated by a recursive directory listing of +# the windows %HOMEDRIVE%. +proc create_tmp_file { remote_prompt filename } { + set default_err_str "Unknown error in function create_tmp_file" + set err_str $default_err_str + + set cmd "dir %HOMEDRIVE%\\ /S > $filename\r\n" + send $cmd + expect { + $remote_prompt { + set err_str "OK" + } \ + timeout { + set err_str "Function create_tmp_file timed out while creating $filename" + } + } + return $err_str +} + +# This function compares two files on the remote windows host. +proc compare_files { remote_prompt file1 file2 } { + set default_err_str "Unknown error in function compare_files" + set err_str $default_err_str + + set cmd "fc $file1 $file2\r\n" + send $cmd + expect { + "FC: no differences encountered\r\n\r\n\r\n" { + expect_prompt $remote_prompt + set err_str "OK" + } \ + "\*\*\*\*\* $file1" { + expect_prompt $remote_prompt + set err_str "Files $file1 and $file2 differ" + } \ + "\*\*\*\*\* $file2" { + expect_prompt $remote_prompt + set err_str "Files $file1 and $file2 differ" + } \ + timeout { + set err_str "Function compare_files timed out while comparing files $file1 and $file2" + } + } + return $err_str +} + +# This function deletes a file on the remote windows host. +proc delete_file { remote_prompt filename } { + set default_err_str "Unknown error in function delete_file" + set err_str $default_err_str + + set cmd "del $filename\r\n" + send $cmd + expect { + "Could Not" { + expect_prompt $remote_prompt + set err_str $default_err_str + } \ + $remote_prompt { + set err_str "OK" + } \ + timeout { + set err_str "Function delete_file timed oout while deleting $filename" + } + } + return $err_str +} + +# This function copies a text file over telnet from the local unix host +# to the remote windows host. +proc copy_file { remote_prompt in_filename out_filename } { + set default_err_str "Unknown error in function copy_file" + set err_str $default_err_str + + # The octal ASCII code for Control-Z is 032. + set CTRLZ \032 + + # Open local file and read contents. + set in_file [open $in_filename r] + set in_data [read $in_file] + + # Initiate copy on remote host. + set cmd "copy con $out_filename\r\n" + send $cmd + + # Separate $in_data into lines and send to remote host. + set out_data [split $in_data "\n"] + foreach out_line $out_data { + send $out_line + # We might as well do a unix -> windows line conversion. + send "\r\n" + # Are we overwriting an existing file? + # If so, exit so we can handle it. + expect { + "(Yes/No/All)" { + send "NO\r\n" + expect_prompt $remote_prompt + set err_str "File exists" + } \ + $out_line { + set err_str "OK" + } \ + timeout { + set err_str "Function copy_file timed out while copying $in_filename" + } + } + if { $err_str != "OK" } { + return $err_str + } else { + set err_str $default_err_str + } + } + + # ^Z\r to complete the transfer. + send $CTRLZ + send "\r" + expect { + "file(s) copied." { + set err_str [expect_prompt $remote_prompt] + } \ + $remote_prompt { + set err_str $default_err_str + } \ + timeout { + expect_prompt $remote_prompt + set err_str "Function copy_file timed out while finishing copy of $in_filename" + } + } + return $err_str +} + +# This function waits for the command prompt and reports an error on +# timeout. +proc expect_prompt { remote_prompt } { + set default_err_str "Unknown error occurred while waiting for the command prompt" + set err_str $default_err_str + + expect { + $remote_prompt { + set err_str "OK" + } \ + timeout { + set err_str "Timeout occurred while waiting for the command prompt" + } + } + return $err_str +} + +# This function will create a telnet login shell to $remote_host as $username. +# If expected dialogue is not received, return with a specific error if one +# is recognized. Otherwise return a generic error indicating the function +# name. +proc telnet_login { remote_prompt remote_host username password } { + + set default_err_str "Unknown error in function telnet_login" + set err_str $default_err_str + + set cmd "telnet $remote_host\r" + send $cmd + expect { + "login: " { + set err_str "OK" + } \ + "Connection refused" { + set err_str "Connection refused" + } \ + "No route to host" { + set err_str "No route to host" + } \ + timeout { + set err_str "Function telnet_login timed out while waiting for the login prompt" + } + } + if { $err_str != "OK" } { + # Return because something unexpected happened. + return $err_str + } else { + # Reset err_str + set err_str $default_err_str + } + + set cmd "$username\r" + send $cmd + expect { + "password: " { + set err_str "OK" + } \ + timeout { + set err_str "Function telnet_login timed out while waiting for the password prompt" + } + } + if { $err_str != "OK" } { + return $err_str + } else { + set err_str $default_err_str + } + + set cmd "$password\r" + send $cmd + expect { + $remote_prompt { + set err_str "OK" + } \ + "Login Failed" { + set err_str "Telnet login failed" + } \ + timeout { + set err_str "Function telnet_login timed out while waiting for the command prompt" + } + } + return $err_str +} + +proc create_directory { remote_prompt sharepath } { + + set default_err_str "Unknown error in function create_directory" + set err_str $default_err_str + + set cmd "mkdir $sharepath\r\n" + send $cmd + expect { + "already exists" { + expect_prompt $remote_prompt + set err_str "Directory already exists" + } \ + $remote_prompt { + set err_str "OK" + } \ + timeout { + expect_prompt $remote_prompt + set err_str "Timeout reached starting create_directory." + } + } + return $err_str +} + +proc delete_directory { remote_prompt sharepath } { + + set default_err_str "Unknown error in function delete_directory" + set err_str $default_err_str + + set cmd "rmdir /S /Q $sharepath\r\n" + send $cmd + expect { + "Access is denied." { + expect_prompt $remote_prompt + set err_str "Directory access is denied" + } \ + $remote_prompt { + set err_str "OK" + } \ + timeout { + expect_prompt $remote_prompt + set err_str "Timeout reached in delete_directory" + } + } + return $err_str +} + +proc create_share { remote_prompt username sharepath sharename } { + + set default_err_str "Unknown error in function create_share" + set err_str $default_err_str + + set cmd "net share $sharename=$sharepath /GRANT:$username,FULL\r\n" + send $cmd + expect { + "was shared successfully." { + set err_str [expect_prompt $remote_prompt] + } \ + "NET HELPMSG 2118." { + expect_prompt $remote_prompt + set err_str "The name has already been shared" + } \ + $remote_prompt { + set err_str $default_err_str + } \ + timeout { + expect_prompt $remote_prompt + set err_str "Timeout reached in create_share" + } + } + return $err_str +} + +proc delete_share { remote_prompt sharename } { + + set default_err_str "Unknown error in function delete_share" + set err_str $default_err_str + + set cmd "net share $sharename /DELETE\r\n" + send $cmd + expect { + "was deleted successfully." { + set err_str [expect_prompt $remote_prompt] + } \ + "does not exist." { + expect_prompt $remote_prompt + set err_str "The share does not exist" + } \ + $remote_prompt { + set err_str $default_err_str + } \ + timeout { + expect_prompt $remote_prompt + set err_str "Timeout reached in delete_share" + } + } + return $err_str +} + +proc delete_hosts_entry { remote_prompt hosts_file_path backup_hosts_filename } { + + set default_err_str "Unknown error in function delete_hosts_entry" + set err_str $default_err_str + + set cmd "cd $hosts_file_path\r\n" + send $cmd + expect { + "." { + expect_prompt $remote_prompt + set err_str $default_err_str + } \ + $remote_prompt { + set err_str "OK" + } \ + timeout { + expect_prompt $remote_prompt + set err_str "Timeout reached in delete_hosts_entry" + } + } + if { $err_str != "OK" } { + return $err_str + } else { + set err_str $default_err_str + } + + set cmd "move /Y $backup_hosts_filename hosts\r\n" + send $cmd + expect { + "1 file(s) moved." { + set err_str [expect_prompt $remote_prompt] + } \ + "cannot find the file specified." { + expect_prompt $remote_prompt + set err_str "File not found" + } \ + $remote_prompt { + set err_str $default_err_str + } \ + timeout { + expect_prompt $remote_prompt + set err_str "Function delete_hosts_entry timed out while renaming $backup_hosts_filename" + } + } + return $err_str +} + +proc create_hosts_entry { remote_prompt hosts_file_path hostname ip \ + backup_hosts_filename } { + + set default_err_str "Unknown error in function create_hosts_entry" + set err_str $default_err_str + + set cmd "cd $hosts_file_path\r\n" + send $cmd + expect { + "." { + expect_prompt $remote_prompt + set err_str $default_err_str + } \ + $remote_prompt { + set err_str "OK" + } \ + timeout { + expect_prompt $remote_prompt + set err_str "Timeout reached in create_hosts_entry" + } + } + if { $err_str != "OK" } { + return $err_str + } else { + set err_str $default_err_str + } + + set cmd "copy /Y hosts $backup_hosts_filename\r\n" + send $cmd + expect { + "1 file(s) copied." { + set err_str [expect_prompt $remote_prompt] + } \ + "cannot find the file specified." { + expect_prompt $remote_prompt + set err_str "File not found." + } \ + $remote_prompt { + set err_str $default_err_str + } \ + timeout { + expect_prompt $remote_prompt + set err_str "Function create_hosts_entry timed out while copying hosts file" + } + } + if { $err_str != "OK" } { + return $err_str + } else { + set err_str $default_err_str + } + + set cmd "echo $ip $hostname #smbtorture host. >> hosts\r\n" + send $cmd + expect { + $remote_prompt { + set err_str "OK" + } \ + timeout { + expect_prompt $remote_prompt + set err_str "Function create_hosts timed out while updating hosts file" + } + } + return $err_str +} diff --git a/source4/selftest/win/test_win.conf b/source4/selftest/win/test_win.conf new file mode 100644 index 0000000..ed52be9 --- /dev/null +++ b/source4/selftest/win/test_win.conf @@ -0,0 +1,83 @@ + +# perl needs to know to look in $WINTEST_DIR for VMHost.pm. +export PERLLIB=$WINTEST_DIR + +# Command prompt that we are expecting on the windows host. +export SMBTORTURE_REMOTE_PROMPT=">" + +## +## The variables in this section apply to the 'make wintest_dc' set of tests. +## + +# A username and password with admin rights to the DC we're testing against. +export WIN2K3_DC_USERNAME="tortureuser" +export WIN2K3_DC_PASSWORD="torturepass" + +# The domain and realm that the DC is configured for. +export WIN2K3_DC_DOMAIN="WINTESTDC" +export WIN2K3_DC_REALM="wintest.dc" + +# The path to the DC vmware image config file, local to the vmware server. +export WIN2K3_DC_VM_CFG_PATH="/var/lib/vmware/Virtual Machines/Windows Server 2003 DC BuildFarm/Windows 2003 DC BuildFarm.vmx" + +## +## The parameters in this section apply to the 'make wintest' set of tests. +## + +# The username and password we will be testing with. +# This user will need admin rights on the remote windows host. +export SMBTORTURE_USERNAME="tortureuser" +export SMBTORTURE_PASSWORD="torturepass" + +# The name of the workgroup we will be using on the remote windows host. +export SMBTORTURE_WORKGROUP="SMBTEST" + +# The name of and path to the windows share we'll be testing against. +export SMBTORTURE_REMOTE_SHARE_NAME="smbtorture_share" +export SMBTORTURE_REMOTE_SHARE_PATH="%HOMEDRIVE%\smbtorture_shared_dir" + +# Default timeout for the expect scripts to wait for a response from the remote. +export SMBTORTURE_EXPECT_TIMEOUT=30 + +# Path to the local smbtorture binary. +export SMBTORTURE_BIN_PATH="bin/smbtorture" + +# Local system hostname and ip address we'll be adding to the remote's +# hosts file. +export SMBTORTURE_LOCAL_HOSTNAME=$NETBIOSNAME +export SMBTORTURE_LOCAL_IP="192.168.100.12" + +# Filename of the windows hosts' unedited hosts file. +export REMOTE_BACKUP_HOSTS_FILENAME="hosts.smbtorture" +export REMOTE_HOSTS_FILE_PATH="%SYSTEMROOT%\\system32\\drivers\\etc" + +# These coincide with the parameters mktestsetup.sh uses to setup smbd. +export SMBTORTURE_LOCAL_USERNAME="administrator" +export SMBTORTURE_LOCAL_PASSWORD="penguin" +export SMBTORTURE_LOCAL_DOMAIN="SAMBADOMAIN" + +# This is the name of the samba share the windows vm will connect to. +export SMBTORTURE_LOCAL_SHARE_NAME="TMP" + +# This is the drive letter which will be used to mount a share on the windows vm. +export SMBTORTURE_REMOTE_DRIVE_LETTER="X:" + +# This is the name of the file which will be created on the windows vm +# and used for samba server tests. +export SMBTORTURE_TMP_FILENAME="smbtorture.tmp" + +# The path to the vmware image config file local to the vmware server. +export VM_CFG_PATH="/var/lib/vmware/Virtual Machines/Win2k3-BuildFarm/Win2k3-BuildFarm.vmx" + +# In order to copy files and execute programs on the guest vm, +# we need administrator-level credentials to log in with. +export GUEST_ADMIN_USERNAME="administrator" +export GUEST_ADMIN_PASSWORD="adminpass" + +# These parameters are optional. If not specified, the script tries to access +# a local vmware server as the executing user. +# logged-in user running the script are used. +export HOST_SERVER_NAME="vmhost" +export HOST_SERVER_PORT=902 +export HOST_USERNAME="vmuser" +export HOST_PASSWORD="vmpass" diff --git a/source4/selftest/win/vm_get_ip.pl b/source4/selftest/win/vm_get_ip.pl new file mode 100644 index 0000000..9657a34 --- /dev/null +++ b/source4/selftest/win/vm_get_ip.pl @@ -0,0 +1,48 @@ +#!/usr/bin/perl -w + +# A perl script to connect to a VMware server and get the IP address of a VM. +# Copyright Brad Henry <brad@samba.org> 2006 +# Released under the GNU GPL version 3 or later. + +use VMHost; + +sub check_error { + my $vm = VMHost; + my $custom_err_str = ""; + ($vm, $custom_err_str) = @_; + + my ($err_code, $err_str) = $vm->error; + if ($err_code != 0) { + undef $vm; + die $custom_err_str . "Returned $err_code: $err_str.\n"; + } +} + +# Read in parameters from environment. +my $vm_cfg_path = $ENV{"$ARGV[0]"}; +my $host_server_name = $ENV{'HOST_SERVER_NAME'}; +my $host_server_port = $ENV{'HOST_SERVER_PORT'}; +if (!defined($host_server_port)) { + $host_server_port = 902; +} + +my $host_username = $ENV{'HOST_USERNAME'}; +my $host_password = $ENV{'HOST_PASSWORD'}; +my $guest_admin_username = $ENV{'GUEST_ADMIN_USERNAME'}; +my $guest_admin_password = $ENV{'GUEST_ADMIN_PASSWORD'}; + +my $vm = VMHost; + +$vm->host_connect($host_server_name, $host_server_port, $host_username, + $host_password, $vm_cfg_path, $guest_admin_username, + $guest_admin_password); +check_error($vm, "Error in \$vm->host_connect().\n"); + +my $guest_ip = $vm->get_guest_ip(); +check_error($vm, "Error in \$vm->get_guest_ip().\n"); + +print $guest_ip; + +undef $vm; + +exit 0; diff --git a/source4/selftest/win/vm_load_snapshot.pl b/source4/selftest/win/vm_load_snapshot.pl new file mode 100644 index 0000000..35e80ba --- /dev/null +++ b/source4/selftest/win/vm_load_snapshot.pl @@ -0,0 +1,46 @@ +#!/usr/bin/perl -w + +# A perl script to connect to a VMware server and revert a VM snapshot. +# Copyright Brad Henry <brad@samba.org> 2006 +# Released under the GNU GPL version 3 or later. + +use VMHost; + +sub check_error { +my $vm = VMHost; + my $custom_err_str = ""; + ($vm, $custom_err_str) = @_; + + my ($err_code, $err_str) = $vm->error; + if ($err_code != 0) { + undef $vm; + die $custom_err_str . "Returned $err_code: $err_str.\n"; + } +} + +# Read in parameters from environment. +my $vm_cfg_path = $ENV{'VM_CFG_PATH'}; +my $host_server_name = $ENV{'HOST_SERVER_NAME'}; +my $host_server_port = $ENV{'HOST_SERVER_PORT'}; +if (!defined($host_server_port)) { + $host_server_port = 902; +} + +my $host_username = $ENV{'HOST_USERNAME'}; +my $host_password = $ENV{'HOST_PASSWORD'}; +my $guest_admin_username = $ENV{'GUEST_ADMIN_USERNAME'}; +my $guest_admin_password = $ENV{'GUEST_ADMIN_PASSWORD'}; + +my $vm = VMHost; + +$vm->host_connect($host_server_name, $host_server_port, $host_username, + $host_password, $vm_cfg_path, $guest_admin_username, + $guest_admin_password); +check_error($vm, "Error in \$vm->host_connect().\n"); + +$vm->revert_snapshot(); +check_error($vm, "Error in \$vm->revert_snapshot().\n"); + +undef $vm; + +exit 0; diff --git a/source4/selftest/win/wintest_2k3_dc.sh b/source4/selftest/win/wintest_2k3_dc.sh new file mode 100755 index 0000000..4852e22 --- /dev/null +++ b/source4/selftest/win/wintest_2k3_dc.sh @@ -0,0 +1,120 @@ +#!/bin/sh + +if [ $# -lt 1 ]; then + cat <<EOF +Usage: wintest_2k3_dc.sh TESTGROUP +EOF + exit 1 +fi + +TESTGROUP=$1 + +if [ -z $WINTEST_DIR ]; then + echo "Environment variable WINTEST_DIR not found." + exit 1 +fi + +# This variable is defined in the per-hosts .fns file for build-farm hosts that run windows tests. +if [ -z $WINTESTCONF ]; then + echo "Please point environment variable WINTESTCONF to your test_win.conf file." + exit 1 +fi + +. $WINTESTCONF +. $WINTEST_DIR/wintest_functions.sh + +export WIN2K3_DC_REMOTE_HOST=$(perl -I$WINTEST_DIR $WINTEST_DIR/vm_get_ip.pl WIN2K3_DC_VM_CFG_PATH) + +if [ -z $WIN2K3_DC_REMOTE_HOST ]; then + # Restore snapshot to ensure VM is in a known state, then exit. + restore_snapshot "Test failed to get the IP address of the windows 2003 DC." "$WIN2K3_DC_VM_CFG_PATH" + exit 1 +fi + +server=$WIN2K3_DC_REMOTE_HOST +username=$WIN2K3_DC_USERNAME +password=$WIN2K3_DC_PASSWORD +domain=$WIN2K3_DC_DOMAIN +realm=$WIN2K3_DC_REALM + +OPTIONS="-U$username%$password -W $domain --option realm=$realm" + +all_errs=0 + +on_error() +{ + name=$1 + + all_errs=$(expr $all_errs + 1) + restore_snapshot "$name test failed." "$WIN2K3_DC_VM_CFG_PATH" +} + +drsuapi_tests() +{ + + name="RPC-DRSUAPI on ncacn_ip_tcp with seal" + bin/smbtorture \ + ncacn_ip_tcp:$server[seal] $OPTIONS \ + RPC-DRSUAPI || on_error "$name" + + name="RPC-DRSUAPI on ncacn_ip_tcp with seal,bigendian" + bin/smbtorture \ + ncacn_ip_tcp:$server[seal,bigendian] $OPTIONS \ + RPC-DRSUAPI || on_error "$name" +} + +spoolss_tests() +{ + + name="RPC-SPOOLSS on ncacn_np" + bin/smbtorture \ + ncacn_np:$server $OPTIONS \ + RPC-SPOOLSS || on_error "$name" +} + +ncacn_ip_tcp_tests() +{ + bindopt=$1 + transport="ncacn_ip_tcp" + tests="RPC-SCHANNEL RPC-EPMAPPER RPC-SAMR RPC-NETLOGON RPC-LSA RPC-SAMLOGON RPC-SAMSYNC RPC-MULTIBIND" + + for bindoptions in $bindopt; do + for t in $tests; do + name="$t on $transport with $bindoptions" + bin/smbtorture $TORTURE_OPTIONS \ + $transport:$server[$bindoptions] \ + $OPTIONS $t || on_error "$name" + done + done +} + +ncacn_np_tests() +{ + bindopt=$1 + transport="ncacn_np" + tests="RPC-SCHANNEL RPC-DSSETUP RPC-EPMAPPER RPC-SAMR RPC-WKSSVC RPC-SRVSVC RPC-EVENTLOG RPC-NETLOGON RPC-LSA RPC-SAMLOGON RPC-SAMSYNC RPC-MULTIBIND RPC-WINREG" + + for bindoptions in $bindopt; do + for t in $tests; do + name="$t on $transport with $bindoptions" + bin/smbtorture $TORTURE_OPTIONS \ + $transport:$server[$bindoptions] \ + $OPTIONS $t || on_error "$name" + done + done +} + +bindoptions="padcheck connect sign seal ntlm,sign ntml,seal $VALIDATE bigendian" + +case $TESTGROUP in +RPC-DRSUAPI) drsuapi_tests ;; +RPC-SPOOLSS) spoolss_tests ;; +ncacn_ip_tcp) ncacn_ip_tcp_tests $bindoptions ;; +ncacn_np) ncacn_np_tests $bindoptions ;; +*) + echo "$TESTGROUP is not a known set of tests." + exit 1 + ;; +esac + +exit $all_errs diff --git a/source4/selftest/win/wintest_base.sh b/source4/selftest/win/wintest_base.sh new file mode 100755 index 0000000..6905b5e --- /dev/null +++ b/source4/selftest/win/wintest_base.sh @@ -0,0 +1,68 @@ +#!/bin/sh + +. selftest/test_functions.sh + +. selftest/win/wintest_functions.sh + +# This variable is defined in the per-hosts .fns file. +. $WINTESTCONF + +if [ $# -lt 4 ]; then + cat <<EOF +Usage: test_net.sh SERVER USERNAME PASSWORD DOMAIN +EOF + exit 1 +fi + +server="$1" +username="$2" +password="$3" +domain="$4" +shift 4 + +export SMBTORTURE_REMOTE_HOST=$server + +base_tests="BASE-UNLINK BASE-ATTR BASE-DELETE BASE-TCON BASE-OPEN BASE-CHKPATH" + +all_errs=0 +err=0 + +on_error() +{ + errstr=$1 + + all_errs=$(expr $all_errs + 1) + restore_snapshot $errstr "$VM_CFG_PATH" +} + +for t in $base_tests; do + test_name="$t / WINDOWS SERVER" + echo -e "\n$test_name SETUP PHASE" + + setup_share_test + + if [ $err_rtn -ne 0 ]; then + # If test setup fails, load VM snapshot and skip test. + on_error "\n$test_name setup failed, skipping test." + else + echo -e "\n$test_name setup completed successfully." + + $SMBTORTURE_BIN_PATH -U $username%$password \ + -W $domain //$server/$SMBTORTURE_REMOTE_SHARE_NAME \ + $t || err=1 + if [ $err -ne 0 ]; then + on_error "\n$test_name failed." + else + echo -e "\n$test_name CLEANUP PHASE" + remove_share_test + if [ $err_rtn -ne 0 ]; then + # If cleanup fails, restore VM snapshot. + on_error "\n$test_name removal failed." + else + echo -e "\n$test_name removal completed successfully." + fi + fi + fi +done + +exit $all_errs diff --git a/source4/selftest/win/wintest_client.exp b/source4/selftest/win/wintest_client.exp new file mode 100644 index 0000000..ccf5d06 --- /dev/null +++ b/source4/selftest/win/wintest_client.exp @@ -0,0 +1,95 @@ +# An expect script to create a temporary file, map a share, copy the file to the share, +# and compare the contents of the two files. +# Copyright Brad Henry <brad@samba.org> 2006 +# Released under the GNU GPL version 3 or later. + +proc run_test { remote_prompt tmp_filename share_drive host_drive buildhost_ip buildhost_share username domain password } { + + # Create the temp file on the windows host and connect to the samba share. + set host_tmpfile "$host_drive\\$tmp_filename" + set err_str [create_tmp_file $remote_prompt $host_tmpfile] + if { $err_str != "OK" } { + return $err_str + } + + set buildhost_sharepoint "\\\\$buildhost_ip\\$buildhost_share" + set err_str [map_share $remote_prompt $share_drive $buildhost_sharepoint $username $domain $password] + if { $err_str != "OK" } { + return $err_str + } + + # Copy the temp file to the share and compare its contents with the original. + set share_tmpfile "$share_drive\\$tmp_filename" + set xcopy_options "" + set err_str [xcopy_file $remote_prompt $host_tmpfile $share_tmpfile $xcopy_options] + if { $err_str != "OK" } { + return $err_str + } + + set err_str [compare_files $remote_prompt $host_tmpfile $share_tmpfile] + if { $err_str != "OK" } { + return $err_str + } + + # Remove files and unmap share. + set err_str [delete_file $remote_prompt $share_tmpfile] + if { $err_str != "OK" } { + return $err_str + } + set err_str [delete_file $remote_prompt $host_tmpfile] + if { $err_str != "OK" } { + return $err_str + } + + set err_str [unmap_share $remote_prompt $share_drive] + if {$err_str != "OK" } { + return $err_str + } + + return $err_str +} + +# Read parameters. +set remote_prompt $env(SMBTORTURE_REMOTE_PROMPT) +set remote_host $env(SMBTORTURE_REMOTE_HOST) +set username $env(SMBTORTURE_USERNAME) +set password $env(SMBTORTURE_PASSWORD) +set timeout $env(SMBTORTURE_EXPECT_TIMEOUT) + +set tmp_filename $env(SMBTORTURE_TMP_FILENAME) + +set share_drive $env(SMBTORTURE_REMOTE_DRIVE_LETTER) +set host_drive "%HOMEDRIVE%" + +set buildhost_ip $env(SMBTORTURE_LOCAL_IP) +set buildhost_share $env(SMBTORTURE_LOCAL_SHARE_NAME) +set buildhost_username $env(SMBTORTURE_LOCAL_USERNAME) +set buildhost_domain $env(SMBTORTURE_LOCAL_DOMAIN) +set buildhost_password $env(SMBTORTURE_LOCAL_PASSWORD) + +set err_val [spawn $env(SHELL)] +if {$err_val == 0} { + puts stderr "Expect failed while spawning a shell process." + exit $err_val +} + +set err_str [telnet_login $remote_prompt $remote_host $username $password] +if {$err_str != "OK"} { + puts stderr "\nFunction telnet_login failed during Samba server testing." + puts stderr "Error was: $err_str." + exit 1 +} + +set err_str [run_test $remote_prompt $tmp_filename $share_drive $host_drive $buildhost_ip $buildhost_share $buildhost_username $buildhost_domain $buildhost_password] +if {$err_str != "OK"} { + puts stderr "\nFunction run_test failed during Samba server testing." + puts stderr "Error was: $err_str." + + # Log off from the telnet server. + send "exit\r\n" + exit 1 +} + +# Log off from the telnet server. +send "exit\r\n" +exit 0 diff --git a/source4/selftest/win/wintest_client.sh b/source4/selftest/win/wintest_client.sh new file mode 100755 index 0000000..b956c71 --- /dev/null +++ b/source4/selftest/win/wintest_client.sh @@ -0,0 +1,26 @@ +#!/bin/sh + +. selftest/test_functions.sh + +. selftest/win/wintest_functions.sh + +# This variable is defined in the per-hosts .fns file. +. $WINTESTCONF + +export SMBTORTURE_REMOTE_HOST=$1 + +test_name="WINDOWS CLIENT / SAMBA SERVER SHARE" + +cat $WINTEST_DIR/common.exp >$TMPDIR/client_test.exp +cat $WINTEST_DIR/wintest_client.exp >>$TMPDIR/client_test.exp + +expect $TMPDIR/client_test.exp || all_errs=$(expr $all_errs + 1) + +if [ $all_errs ] >0; then + # Restore snapshot to ensure VM is in a known state. + restore_snapshot "\n$test_name failed." "$VM_CFG_PATH" +fi + +rm -f $TMPDIR/client_test.exp + +exit $all_errs diff --git a/source4/selftest/win/wintest_functions.sh b/source4/selftest/win/wintest_functions.sh new file mode 100755 index 0000000..9b6bed9 --- /dev/null +++ b/source4/selftest/win/wintest_functions.sh @@ -0,0 +1,54 @@ +#!/bin/sh + +# Setup the windows environment. +# This was the best way I could figure out including library files +# for the moment. +# I was finding that "cat common.exp wintest_setup.exp | expect -f -" +# fails to run, but exits with 0 status something like 1% of the time. + +setup_share_test() +{ + echo -e "\nSetting up windows environment." + cat $WINTEST_DIR/common.exp >$TMPDIR/setup.exp + cat $WINTEST_DIR/wintest_setup.exp >>$TMPDIR/setup.exp + expect $TMPDIR/setup.exp + err_rtn=$? + rm -f $TMPDIR/setup.exp +} + +# Clean up the windows environment after the test has run or failed. +remove_share_test() +{ + echo -e "\nCleaning up windows environment." + cat $WINTEST_DIR/common.exp >$TMPDIR/remove.exp + cat $WINTEST_DIR/wintest_remove.exp >>$TMPDIR/remove.exp + expect $TMPDIR/remove.exp + err_rtn=$? + rm -f $TMPDIR/remove.exp +} + +restore_snapshot() +{ + err_str=$1 + VMX_PATH=$2 + + # Display the error that caused us to restore the snapshot. + echo -e $err_str + + if [ -z $HOST_SERVER_NAME ]; then + # The vmware server is running locally. + vmrun revertToSnapshot "$VMX_PATH" + err_rtn=$? + else + vmrun -h $HOST_SERVER_NAME -P $HOST_SERVER_PORT \ + -u $HOST_USERNAME -p $HOST_PASSWORD \ + revertToSnapshot "$VMX_PATH" + err_rtn=$? + fi + + if [ $err_rtn -eq 0 ]; then + echo "Snapshot restored." + else + echo "Error $err_rtn restoring snapshot!" + fi +} diff --git a/source4/selftest/win/wintest_net.sh b/source4/selftest/win/wintest_net.sh new file mode 100755 index 0000000..429be6c --- /dev/null +++ b/source4/selftest/win/wintest_net.sh @@ -0,0 +1,63 @@ +#!/bin/sh + +. selftest/test_functions.sh + +. selftest/win/wintest_functions.sh + +# This variable is defined in the per-hosts .fns file. +. $WINTESTCONF + +if [ $# -lt 4 ]; then + cat <<EOF +Usage: test_net.sh SERVER USERNAME PASSWORD DOMAIN +EOF + exit 1 +fi + +server="$1" +username="$2" +password="$3" +domain="$4" +shift 4 + +ncacn_np_tests="NET-API-LOOKUP NET-API-LOOKUPHOST NET-API-RPCCONN-BIND NET-API-RPCCONN-SRV NET-API-RPCCONN-DC NET-API-RPCCONN-DCINFO NET-API-LISTSHARES" +#These tests fail on ncacn_np: NET-API-LOOKUPPDC NET-API-CREATEUSER NET-API-DELETEUSER + +ncalrpc_tests="NET-API-RPCCONN-SRV NET-API-RPCCONN-DC NET-API-RPCCONN-DCINFO NET-API-LISTSHARES" +#These tests fail on ncalrpc: NET-API-CREATEUSER NET-API-DELETEUSER + +ncacn_ip_tcp_tests="NET-API-LOOKUP NET-API-LOOKUPHOST NET-API-RPCCONN-SRV NET-API-RPCCONN-DC NET-API-RPCCONN-DCINFO NET-API-LISTSHARES" +#These tests fail on ncacn_ip_tcp: NET-API-LOOKUPPDC NET-API-CREATEUSER NET-API-DELETEUSER + +bind_options="seal,padcheck bigendian" + +test_type="ncalrpc ncacn_np ncacn_ip_tcp" + +all_errs=0 + +on_error() +{ + errstr=$1 + + all_errs=$(expr $all_errs + 1) + restore_snapshot "$errstr" "$VM_CFG_PATH" +} + +for o in $bind_options; do + for transport in $test_type; do + case $transport in + ncalrpc) net_test=$ncalrpc_tests ;; + ncacn_np) net_test=$ncacn_np_tests ;; + ncacn_ip_tcp) net_test=$ncacn_ip_tcp_tests ;; + esac + + for t in $net_test; do + test_name="$t on $transport with $o" + $SMBTORTURE_BIN_PATH -U $username%$password \ + -W $domain $transport:$server[$o] \ + $t || on_error "\n$test_name failed." + done + done +done + +exit $all_errs diff --git a/source4/selftest/win/wintest_raw.sh b/source4/selftest/win/wintest_raw.sh new file mode 100755 index 0000000..c22dacd --- /dev/null +++ b/source4/selftest/win/wintest_raw.sh @@ -0,0 +1,69 @@ +#!/bin/sh + +. selftest/test_functions.sh + +. selftest/win/wintest_functions.sh + +# This variable is defined in the per-hosts .fns file. +. $WINTESTCONF + +if [ $# -lt 4 ]; then + cat <<EOF +Usage: test_net.sh SERVER USERNAME PASSWORD DOMAIN +EOF + exit 1 +fi + +server="$1" +username="$2" +password="$3" +domain="$4" +shift 4 + +export SMBTORTURE_REMOTE_HOST=$server + +raw_tests="RAW-QFILEINFO RAW-SFILEINFO-BASE RAW-MKDIR RAW-SEEK RAW-OPEN RAW-WRITE RAW-UNLINK RAW-READ RAW-CLOSE RAW-IOCTL RAW-RENAME RAW-EAS RAW-STREAMS" +# This test fails: RAW-QFSINFO + +all_errs=0 +err=0 + +on_error() +{ + errstr=$1 + all_errs=$(expr $all_errs + 1) + + restore_snapshot "$errstr" "$VM_CFG_PATH" +} + +for t in $raw_tests; do + test_name="$t / WINDOWS SERVER" + echo -e "\n$test_name SETUP PHASE" + + setup_share_test + + if [ $err_rtn -ne 0 ]; then + # If test setup fails, load VM snapshot and skip test. + on_error "\n$test_name setup failed, skipping test." + else + echo -e "\n$test_name setup completed successfully." + + $SMBTORTURE_BIN_PATH -U $username%$password -W $domain \ + //$server/$SMBTORTURE_REMOTE_SHARE_NAME \ + $t || err=1 + if [ $err -ne 0 ]; then + on_error "\n$test_name failed." + else + echo -e "\n$test_name CLEANUP PHASE" + remove_share_test + if [ $err_rtn -ne 0 ]; then + # If cleanup fails, restore VM snapshot. + on_error "\n$test_name removal failed." + else + echo -e "\n$test_name removal completed successfully." + fi + fi + fi +done + +exit $all_errs diff --git a/source4/selftest/win/wintest_remove.exp b/source4/selftest/win/wintest_remove.exp new file mode 100644 index 0000000..36dc4a7 --- /dev/null +++ b/source4/selftest/win/wintest_remove.exp @@ -0,0 +1,71 @@ +# An expect script to remove a directory and share which was +# previously setup for an smbtorture test. +# Copyright Brad Henry <brad@samba.org> 2006 +# Released under the GNU GPL version 3 or later. + +proc remove_test { remote_prompt sharepath sharename hosts_file_path \ + backup_hosts_filename } { + + set err_str [delete_share $remote_prompt $sharename] + if { $err_str != "OK" } { + puts stderr "Error in function delete_share: $err_str." + puts stderr "Function remove_test will continue." + } + + set err_str [delete_directory $remote_prompt $sharepath] + if { $err_str != "OK" } { + puts stderr "Error in function delete_directory: $err_str." + puts stderr "Function remove_test will continue." + } + + # Overwrite the current hosts file with the backup we made during setup. + set err_str [delete_hosts_entry $remote_prompt $hosts_file_path \ + $backup_hosts_filename] + if { $err_str != "OK" } { + puts stderr "Error in function delete_hosts_entry: $err_str." + puts stderr "Function remove_test will continue." + } + return $err_str +} + +# read parameters +set remote_host $env(SMBTORTURE_REMOTE_HOST) +set remote_prompt $env(SMBTORTURE_REMOTE_PROMPT) + +set username $env(SMBTORTURE_USERNAME) +set password $env(SMBTORTURE_PASSWORD) + +set timeout $env(SMBTORTURE_EXPECT_TIMEOUT) + +set sharepath $env(SMBTORTURE_REMOTE_SHARE_PATH) +set sharename $env(SMBTORTURE_REMOTE_SHARE_NAME) + +set backup_hosts_filename $env(REMOTE_BACKUP_HOSTS_FILENAME) +set hosts_file_path $env(REMOTE_HOSTS_FILE_PATH) + +set err_val [spawn $env(SHELL)] +if {$err_val == 0} { + puts stderr "Expect failed while spawning a shell process." + exit $err_val +} + +set err_str [telnet_login $remote_prompt $remote_host $username $password] +if {$err_str != "OK"} { + puts stderr "\nFunction telnet_login failed during cleanup." + puts stderr "Error was: $err_str." + exit 1 +} + +set err_str [remove_test $remote_prompt $sharepath $sharename \ + $hosts_file_path $backup_hosts_filename] +if {$err_str != "OK"} { + puts stderr "\nFunction remove_test failed." + puts stderr "Error was: $err_str." + # Log off from the telnet server. + send "exit\r\n" + exit 1 +} + +# Log off from the telnet server. +send "exit\r\n" +exit 0 diff --git a/source4/selftest/win/wintest_rpc.sh b/source4/selftest/win/wintest_rpc.sh new file mode 100755 index 0000000..03ac6a8 --- /dev/null +++ b/source4/selftest/win/wintest_rpc.sh @@ -0,0 +1,67 @@ +#!/bin/sh + +. selftest/test_functions.sh + +. selftest/win/wintest_functions.sh + +# This variable is defined in the per-hosts .fns file. +. $WINTESTCONF + +if [ $# -lt 4 ]; then + cat <<EOF +Usage: test_rpc.sh SERVER USERNAME PASSWORD DOMAIN +EOF + exit 1 +fi + +server="$1" +username="$2" +password="$3" +domain="$4" +shift 4 + +ncacn_np_tests="RPC-SRVSVC RPC-UNIXINFO RPC-ECHO RPC-DSSETUP RPC-ALTERCONTEXT RPC-MULTIBIND" +# These tests fail on ncacn_np: RPC-SPOOLSS RPC-SCHANNEL RPC-JOIN RPC-LSA +# RPC-NETLOGON + +ncalrpc_tests="RPC-UNIXINFO RPC-ECHO" +# These tests fail on ncalrpc: RPC-SCHANNEL RPC-JOIN RPC-LSA RPC-DSSETUP +# RPC-ALTERCONTEXT RPC-MULTIBIND RPC-NETLOGON + +ncacn_ip_tcp_tests="RPC-UNIXINFO RPC-ECHO" +# These tests fail on ncacn_ip_tcp: RPC-SCHANNEL RPC-JOIN RPC-LSA RPC-DSSETUP +# RPC-ALTERCONTEXT RPC-MULTIBIND RPC-NETLOGON + +bind_options="seal,padcheck bigendian" + +test_type="ncalrpc ncacn_np ncacn_ip_tcp" + +all_errs=0 + +on_error() +{ + errstr=$1 + all_errs=$(expr $all_errs + 1) + + restore_snapshot "$errstr" "$VM_CFG_PATH" +} + +for o in $bind_options; do + for transport in $test_type; do + case $transport in + ncalrpc) rpc_test=$ncalrpc_tests ;; + ncacn_np) rpc_test=$ncacn_np_tests ;; + ncacn_ip_tcp) rpc_test=$ncacn_ip_tcp_tests ;; + esac + + for t in $rpc_test; do + test_name="$t on $transport with $o" + + $SMBTORTURE_BIN_PATH -U $username%$password \ + -W $domain $transport:$server[$o] \ + $t || on_error "\n$test_name failed." + done + done +done + +exit $all_errs diff --git a/source4/selftest/win/wintest_setup.exp b/source4/selftest/win/wintest_setup.exp new file mode 100644 index 0000000..c48ad14 --- /dev/null +++ b/source4/selftest/win/wintest_setup.exp @@ -0,0 +1,104 @@ +# An expect script to setup a directory and share for an smbtorture test. +# Copyright Brad Henry <brad@samba.org> 2006 +# Released under the GNU GPL version 3 or later. + +proc setup_test { remote_prompt sharepath sharename username local_hostname \ + local_ip hosts_file_path backup_hosts_filename } { + + # If creating the directory fails, remove, then + # re-create the directory. + set err_str [create_directory $remote_prompt $sharepath] + if { $err_str != "OK" } { + if { $err_str != "Directory already exists" } { + puts stderr "\nUnexpected error occurred in setup_test.\n" + puts stderr "Function create_directory returned $err_str." + } else { + puts stdout "\nDirectory $sharepath exists." + } + puts stdout "Re-creating directory $sharepath." + + set err_str [delete_directory $remote_prompt $sharepath] + if { $err_str != "OK" } { + return $err_str + } + set err_str [create_directory $remote_prompt $sharepath] + if { $err_str != "OK" } { + return $err_str + } + } + + # If creating the share fails, remove, then + # re-create the share. + set err_str [create_share $remote_prompt $username $sharepath \ + $sharename] + if { $err_str != "OK" } { + if { $err_str != "The name has already been shared" } { + puts stderr "\nUnexpected error occurred in setup_test." + puts stderr "Function create_share returned $err_str." + } else { + puts stdout "\nShare $sharename exists." + } + puts stdout "Re-creating share $sharename." + + set err_str [delete_share $remote_prompt $sharename] + if { $err_str != "OK" } { + return $err_str + } + set err_str [create_share $remote_prompt $username $sharepath \ + $sharename] + if { $err_str != "OK" } { + return $err_str + } + } + + # Add a hosts file entry on the windows machine for the smbtorture host. + set err_str [create_hosts_entry $remote_prompt $hosts_file_path \ + $local_hostname $local_ip $backup_hosts_filename] + return $err_str +} + +# Read parameters. +set remote_host $env(SMBTORTURE_REMOTE_HOST) +set remote_prompt $env(SMBTORTURE_REMOTE_PROMPT) + +set username $env(SMBTORTURE_USERNAME) +set password $env(SMBTORTURE_PASSWORD) + +set timeout $env(SMBTORTURE_EXPECT_TIMEOUT) + +set sharepath $env(SMBTORTURE_REMOTE_SHARE_PATH) +set sharename $env(SMBTORTURE_REMOTE_SHARE_NAME) + +set local_hostname $env(SMBTORTURE_LOCAL_HOSTNAME) +set local_ip $env(SMBTORTURE_LOCAL_IP) + +set backup_hosts_filename $env(REMOTE_BACKUP_HOSTS_FILENAME) +set hosts_file_path $env(REMOTE_HOSTS_FILE_PATH) + +set err_val [spawn $env(SHELL)] +if {$err_val == 0} { + puts stderr "Expect failed while spawning a shell process." + exit $err_val +} + +set err_str [telnet_login $remote_prompt $remote_host $username $password] +if {$err_str != "OK"} { + puts stderr "\nFunction telnet_login failed during setup." + puts stderr "Error was: $err_str." + exit 1 +} + +set err_str [setup_test $remote_prompt $sharepath $sharename $username \ + $local_hostname $local_ip $hosts_file_path \ + $backup_hosts_filename] +if {$err_str != "OK"} { + puts stderr "\nFunction setup_test failed during setup." + puts stderr "Error was: $err_str." + # Log off from the telnet server. + send "exit\r\n" + exit 1 +} + +# Log off from the telnet server. +send "exit\r\n" +exit 0 |