You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@vcl.apache.org by ar...@apache.org on 2010/09/13 19:43:19 UTC
svn commit: r996613 [2/3] - in
/incubator/vcl/trunk/managementnode/lib/VCL/Module/OS: Windows.pm
Windows/Version_5.pm Windows/Version_6.pm
Modified: incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows.pm
URL: http://svn.apache.org/viewvc/incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows.pm?rev=996613&r1=996612&r2=996613&view=diff
==============================================================================
--- incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows.pm (original)
+++ incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows.pm Mon Sep 13 17:43:19 2010
@@ -966,7 +966,8 @@ sub create_directory {
my $management_node_keys = $self->data->get_management_node_keys();
my $computer_node_name = $self->data->get_computer_node_name();
-
+ my $system32_path = $self->get_system32_path() || return;
+
my @paths;
# Get 1 or more paths from the subroutine arguments
@@ -990,7 +991,7 @@ sub create_directory {
notify($ERRORS{'DEBUG'}, 0, "attempting to create directory: $path");
# Assemble the Windows shell mkdir command and execute it
- my $mkdir_command = $self->get_system32_path() . '/cmd.exe /c "mkdir \\"' . $path . '\\""';
+ my $mkdir_command = $system32_path . '/cmd.exe /c "mkdir \\"' . $path . '\\""';
my ($mkdir_exit_status, $mkdir_output) = run_ssh_command($computer_node_name, $management_node_keys, $mkdir_command, '', '', 1);
if (defined($mkdir_exit_status) && $mkdir_exit_status == 0) {
notify($ERRORS{'OK'}, 0, "directory created on $computer_node_name: $path, output:\n@{$mkdir_output}");
@@ -1008,7 +1009,7 @@ sub create_directory {
}
# Make sure directory was created
- if (!$self->filesystem_entry_exists($path)) {
+ if (!$self->file_exists($path)) {
notify($ERRORS{'WARNING'}, 0, "filesystem entry does not exist on $computer_node_name: $path");
$directories_not_created++;
next;
@@ -1047,122 +1048,72 @@ sub delete_file {
my $management_node_keys = $self->data->get_management_node_keys();
my $computer_node_name = $self->data->get_computer_node_name();
-
+ my $system32_path = $self->get_system32_path() || return;
+
# Get file path subroutine argument
- my $path = shift;
- if (!$path) {
+ my $path_argument = shift;
+ if (!$path_argument) {
notify($ERRORS{'WARNING'}, 0, "file path was not specified as an argument");
return;
}
- my $path_unix = $self->format_path_unix($path);
- my $path_dos = $self->format_path_dos($path);
+ my $path_unix = $self->format_path_unix($path_argument);
+ my $path_dos = $self->format_path_dos($path_argument);
- if (!$self->filesystem_entry_exists($path)) {
- notify($ERRORS{'DEBUG'}, 0, "file not deleted because it does not exist: $path");
- return 1;
- }
+ notify($ERRORS{'DEBUG'}, 0, "attempting to delete file: '$path_argument'");
- notify($ERRORS{'DEBUG'}, 0, "attempting to delete file: $path");
+ # Assemble a set of commands concatenated together
+ # Try to take ownership, set the permissions, then delete the file using both Cygwin bash and Windows commands
+ # This should allow files to be deleted with restrictive ownership, permissions, and attributes
- # Run chmod
- my $chmod_command = "chmod -Rv 777 $path_unix";
- my ($chmod_exit_status, $chmod_output) = run_ssh_command($computer_node_name, $management_node_keys, $chmod_command, '', '', 1);
- if (defined($chmod_exit_status) && $chmod_exit_status == 0) {
- notify($ERRORS{'DEBUG'}, 0, "set permissions to 777 on $path_unix");
- }
- elsif ($chmod_exit_status) {
- notify($ERRORS{'WARNING'}, 0, "failed to set permissions to 777 on $path_unix, exit status: $chmod_exit_status, output:\n@{$chmod_output}");
- }
- else {
- notify($ERRORS{'WARNING'}, 0, "failed to run SSH command to set permissions to 777 on $path_unix");
- }
-
- # Assemble the Windows shell del command and execute it
- my $rm_command = "rm -rfv $path_unix";
- my ($rm_exit_status, $rm_output) = run_ssh_command($computer_node_name, $management_node_keys, $rm_command, '', '', 1);
- if ($rm_output && grep(/removed/i, @{$rm_output})) {
- my $files_deleted = grep(/removed \W/i, @{$rm_output});
- my $directories_deleted = grep(/removed directory/i, @{$rm_output});
- notify($ERRORS{'OK'}, 0, "deleted $path_unix using rm, files deleted: $files_deleted, directories deleted: $directories_deleted");
- }
- elsif (defined($rm_exit_status) && $rm_exit_status == 0) {
- notify($ERRORS{'OK'}, 0, "file either deleted or does not exist on $computer_node_name: $path_unix, output:\n@{$rm_output}");
- }
- elsif (defined($rm_output) && grep(/Circular directory structure/i, @{$rm_output})) {
- notify($ERRORS{'DEBUG'}, 0, "circular directory structure found, rm can't handle this, attempting next deletion method");
- }
- elsif ($rm_exit_status) {
- notify($ERRORS{'WARNING'}, 0, "failed to delete file on $computer_node_name: $path_unix, exit status: $rm_exit_status, output:\n@{$rm_output}");
- }
- else {
- notify($ERRORS{'WARNING'}, 0, "failed to run SSH command to delete file on $computer_node_name: $path_unix");
- }
-
- # Check if file was deleted
- sleep 1;
- if (!$self->filesystem_entry_exists($path)) {
- notify($ERRORS{'DEBUG'}, 0, "confirmed file does not exist: $path");
- return 1;
- }
+ my $command;
+ $command .= "echo ---";
+ $command .= " ; echo Calling chown.exe to change owner to root...";
+ $command .= " ; /usr/bin/chown.exe -Rv root $path_unix 2>&1";
- notify($ERRORS{'DEBUG'}, 0, "file still exists: $path, attempting to delete it using cmd.exe /c del");
+ $command .= " ; echo ---";
+ $command .= " ; echo Calling chmod.exe to change permissions to 777...";
+ $command .= " ; /usr/bin/chmod.exe -Rv 777 $path_unix 2>&1";
- # rm didn't get rid of the file, try del
- # Assemble the Windows shell del command and execute it
- my $del_command = $self->get_system32_path() . '/cmd.exe /c "del /s /q /f /a \\"' . $path_dos . '\\""';
- my ($del_exit_status, $del_output) = run_ssh_command($computer_node_name, $management_node_keys, $del_command, '', '', 1);
- if ($del_output && (my $deleted_count = grep(/deleted file/i, @{$del_output}))) {
- notify($ERRORS{'OK'}, 0, "deleted $path_dos using del, files deleted: $deleted_count");
- }
- elsif (defined($del_exit_status) && $del_exit_status == 0) {
- notify($ERRORS{'DEBUG'}, 0, "file does not exist on $computer_node_name: $path_dos, output:\n@{$del_output}");
- }
- elsif ($del_output && grep(/cannot find/, @{$del_output})) {
- notify($ERRORS{'DEBUG'}, 0, "file not found on $computer_node_name: $path_dos, exit status: $del_exit_status, output:\n@{$del_output}");
- }
- elsif ($del_exit_status) {
- notify($ERRORS{'WARNING'}, 0, "failed to delete file on $computer_node_name: $path_dos, exit status: $del_exit_status, output:\n@{$del_output}");
+ $command .= " ; echo ---";
+ $command .= " ; echo Calling rm.exe to to delete file...";
+ $command .= " ; /usr/bin/rm.exe -rfv $path_unix 2>&1";
+
+ # Add call to rmdir if the path does not contain a wildcard
+ # rmdir does not accept wildcards
+ if ($path_dos !~ /\*/) {
+ $command .= " ; echo ---";
+ $command .= " ; echo Calling 'cmd.exe /c rmdir' to to delete directory...";
+ $command .= " ; $system32_path/cmd.exe /c \"rmdir /s /q \\\"$path_dos\\\"\" 2>&1";
}
- else {
- notify($ERRORS{'WARNING'}, 0, "failed to run SSH command to delete file on $computer_node_name: $path_dos");
+
+ $command .= " ; echo ---";
+ $command .= " ; echo Calling 'cmd.exe /c del' to to delete file...";
+ $command .= " ; $system32_path/cmd.exe /c \"del /s /q /f /a \\\"$path_dos\\\" 2>&1\" 2>&1";
+
+ $command .= " ; echo ---";
+ $command .= " ; echo Calling 'cmd.exe /c dir' to to list remaining files...";
+ $command .= " ; $system32_path/cmd.exe /c \"dir /a /w \\\"$path_dos\\\"\"";
+
+ # Run the command
+ my ($exit_status, $output) = run_ssh_command($computer_node_name, $management_node_keys, $command, '', '', 0);
+ if (!defined($exit_status)) {
+ notify($ERRORS{'WARNING'}, 0, "failed to run SSH command to delete file: '$path_argument'");
+ return;
}
- # Check if file was deleted
+ # Sleep 1 second before checking if file was deleted
sleep 1;
- if (!$self->filesystem_entry_exists($path)) {
- notify($ERRORS{'DEBUG'}, 0, "confirmed file does not exist: $path");
- return 1;
- }
- notify($ERRORS{'DEBUG'}, 0, "file still exists: $path, attempting to delete it using cmd.exe /c rmdir");
-
- # Assemble the Windows shell rmdir command and execute it
- my $rmdir_command = $self->get_system32_path() . '/cmd.exe /c "rmdir /s /q \\"' . $path_dos . '\\""';
- my ($rmdir_exit_status, $rmdir_output) = run_ssh_command($computer_node_name, $management_node_keys, $rmdir_command, '', '', 1);
- if (defined($rmdir_exit_status) && $rmdir_exit_status == 0) {
- notify($ERRORS{'DEBUG'}, 0, "directory deleted using rmdir on $computer_node_name: $path_dos, output:\n@{$rmdir_output}");
- }
- elsif (defined($rmdir_output) && grep(/cannot find the/, @{$rmdir_output})) {
- # Exit status 2 should mean the directory was not found
- notify($ERRORS{'DEBUG'}, 0, "directory to be deleted was not found on $computer_node_name: $path_dos, exit status: $rmdir_exit_status, output:\n@{$rmdir_output}");
- }
- elsif ($rmdir_exit_status) {
- notify($ERRORS{'WARNING'}, 0, "failed to delete directory on $computer_node_name: $path_dos, exit status: $rmdir_exit_status, output:\n@{$rmdir_output}");
+ # Check if file was deleted
+ if ($self->file_exists($path_argument)) {
+ notify($ERRORS{'WARNING'}, 0, "file still exists: '$path_argument, command:\n$command\noutput:\n" . join("\n", @$output));
+ return;
}
else {
- notify($ERRORS{'WARNING'}, 0, "failed to run SSH command to delete directory on $computer_node_name: $path_dos");
- }
-
- # Check if file was deleted
- sleep 1;
- if (!$self->filesystem_entry_exists($path)) {
- notify($ERRORS{'DEBUG'}, 0, "confirmed file does not exist: $path");
+ notify($ERRORS{'DEBUG'}, 0, "deleted file: '$path_argument'");
return 1;
}
-
- notify($ERRORS{'WARNING'}, 0, "file could not be deleted, it still exists: $path");
- return;
}
#/////////////////////////////////////////////////////////////////////////////
@@ -1261,8 +1212,10 @@ sub delete_files_by_pattern {
# Assemble command
# Use find to locate all the files under the base directory matching the pattern specified
- # chmod 777 each file then call rm
- my $command = "/bin/find.exe \"$base_directory\" -mindepth 1 -maxdepth $max_depth -iregex \"$pattern\" -exec chmod 777 {} \\; -exec rm -rvf {} \\;";
+ my $command = "/bin/find.exe \"$base_directory\" -mindepth 1 -maxdepth $max_depth -iregex \"$pattern\"";
+ $command .= " -exec chown -R root {} \\;";
+ $command .= " -exec chmod -R 777 {} \\;";
+ $command .= " -exec rm -rvf {} \\;";
# If the path begins with an environment variable, check if the variable is defined by passing it to cygpath.exe
# Unintended files will be deleted if the environment variable is not defined because the base directory would change from "$TEMP/" to "/"
@@ -1301,7 +1254,7 @@ sub delete_files_by_pattern {
#/////////////////////////////////////////////////////////////////////////////
-=head2 filesystem_entry_exists
+=head2 file_exists
Parameters :
Returns :
@@ -1309,7 +1262,7 @@ sub delete_files_by_pattern {
=cut
-sub filesystem_entry_exists {
+sub file_exists {
my $self = shift;
if (ref($self) !~ /windows/i) {
notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
@@ -1318,6 +1271,7 @@ sub filesystem_entry_exists {
my $management_node_keys = $self->data->get_management_node_keys();
my $computer_node_name = $self->data->get_computer_node_name();
+ my $system32_path = $self->get_system32_path() || return;
# Get the path from the subroutine arguments and make sure it was passed
my $path = shift;
@@ -1326,29 +1280,25 @@ sub filesystem_entry_exists {
return;
}
- # Replace any backslashes or forward slashes with \\
- $path =~ s/[\\\/]/\\\\/g;
-
+ $path = $self->format_path_dos($path);
+
# Assemble the dir command and execute it
- my $dir_command = "cmd.exe /c dir /a /b \"$path\"";
- my ($dir_exit_status, $dir_output) = run_ssh_command($computer_node_name, $management_node_keys, $dir_command, '', '', 1);
- if (defined($dir_output) && grep(/file not found/i, @$dir_output)) {
- notify($ERRORS{'DEBUG'}, 0, "filesystem entry does NOT exist on $computer_node_name: $path");
- return 0;
- }
- elsif ((defined($dir_exit_status) && $dir_exit_status == 0) || (defined($dir_output) && grep(/$path/i, @$dir_output))) {
- notify($ERRORS{'DEBUG'}, 0, "filesystem entry exists on $computer_node_name: $path, dir output:\n" . join("\n", @$dir_output));
- return 1;
- }
- elsif ($dir_exit_status) {
- notify($ERRORS{'WARNING'}, 0, "failed to determine if filesystem entry exists on $computer_node_name: $path, exit status: $dir_exit_status, output:\n@{$dir_output}");
+ my $dir_command = "$system32_path/cmd.exe /c \"dir /a /b \\\"$path\\\"\"";
+ my ($dir_exit_status, $dir_output) = run_ssh_command($computer_node_name, $management_node_keys, $dir_command, '', '', 0);
+ if (!defined($dir_output)) {
+ notify($ERRORS{'WARNING'}, 0, "failed to run SSH command to determine if file exists on $computer_node_name: $path");
return;
}
+
+ if (grep(/file not found/i, @$dir_output)) {
+ notify($ERRORS{'DEBUG'}, 0, "file does NOT exist on $computer_node_name: $path");
+ return 0;
+ }
else {
- notify($ERRORS{'WARNING'}, 0, "failed to run SSH command to determine if filesystem entry exists on $computer_node_name: $path");
- return;
+ notify($ERRORS{'DEBUG'}, 0, "file exists on $computer_node_name: $path, dir output:\n" . join("\n", @$dir_output));
+ return 1;
}
-} ## end sub filesystem_entry_exists
+}
#/////////////////////////////////////////////////////////////////////////////
@@ -1438,8 +1388,9 @@ sub logoff_users {
my $management_node_keys = $self->data->get_management_node_keys();
my $computer_node_name = $self->data->get_computer_node_name();
+ my $system32_path = $self->get_system32_path() || return;
- my ($exit_status, $output) = run_ssh_command($computer_node_name, $management_node_keys, "qwinsta.exe");
+ my ($exit_status, $output) = run_ssh_command($computer_node_name, $management_node_keys, "$system32_path/qwinsta.exe");
if ($exit_status > 0) {
notify($ERRORS{'WARNING'}, 0, "failed to run qwinsta.exe on $computer_node_name, exit status: $exit_status, output:\n@{$output}");
return;
@@ -1485,7 +1436,7 @@ sub logoff_users {
# session to log off (default is current).
# /V Displays information about the actions performed.
# Call logoff.exe, pass it the session
- my ($logoff_exit_status, $logoff_output) = run_ssh_command($computer_node_name, $management_node_keys, "logoff.exe $session_identifier /V");
+ my ($logoff_exit_status, $logoff_output) = run_ssh_command($computer_node_name, $management_node_keys, "$system32_path/logoff.exe $session_identifier /V");
if ($logoff_exit_status == 0) {
notify($ERRORS{'OK'}, 0, "logged off session: $session_identifier, output:\n" . join("\n", @$logoff_output));
}
@@ -1512,8 +1463,7 @@ sub add_users {
notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
return;
}
-
- my $management_node_keys = $self->data->get_management_node_keys();
+
my $computer_node_name = $self->data->get_computer_node_name();
# Attempt to get the user array from the arguments
@@ -1578,8 +1528,7 @@ sub delete_users {
notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
return;
}
-
- my $management_node_keys = $self->data->get_management_node_keys();
+
my $computer_node_name = $self->data->get_computer_node_name();
# Attempt to get the user array from the arguments
@@ -1638,6 +1587,7 @@ sub user_exists {
my $management_node_keys = $self->data->get_management_node_keys();
my $computer_node_name = $self->data->get_computer_node_name();
+ my $system32_path = $self->get_system32_path() || return;
# Attempt to get the username from the arguments
# If no argument was supplied, use the user specified in the DataStructure
@@ -1649,7 +1599,7 @@ sub user_exists {
notify($ERRORS{'DEBUG'}, 0, "checking if user $username exists on $computer_node_name");
# Attempt to query the user account
- my $query_user_command = "net user \"$username\"";
+ my $query_user_command = "$system32_path/net.exe user \"$username\"";
my ($query_user_exit_status, $query_user_output) = run_ssh_command($computer_node_name, $management_node_keys, $query_user_command, '', '', '1');
if (defined($query_user_exit_status) && $query_user_exit_status == 0) {
notify($ERRORS{'DEBUG'}, 0, "user $username exists on $computer_node_name");
@@ -1688,6 +1638,8 @@ sub create_user {
my $management_node_keys = $self->data->get_management_node_keys();
my $computer_node_name = $self->data->get_computer_node_name();
+ my $system32_path = $self->get_system32_path() || return;
+
my $imagemeta_rootaccess = $self->data->get_imagemeta_rootaccess();
# Attempt to get the username from the arguments
@@ -1715,8 +1667,8 @@ sub create_user {
notify($ERRORS{'DEBUG'}, 0, "attempting to add user $username to $computer_node_name ($password)");
# Attempt to add the user account
- my $add_user_command = "net user \"$username\" \"$password\" /ADD /EXPIRES:NEVER /COMMENT:\"Account created by VCL\"";
- $add_user_command .= " && net localgroup \"Remote Desktop Users\" \"$username\" /ADD";
+ my $add_user_command = "$system32_path/net.exe user \"$username\" \"$password\" /ADD /EXPIRES:NEVER /COMMENT:\"Account created by VCL\"";
+ $add_user_command .= " && $system32_path/net.exe localgroup \"Remote Desktop Users\" \"$username\" /ADD";
# Add the user to the Administrators group if imagemeta.rootaccess isn't 0
if (defined($imagemeta_rootaccess) && $imagemeta_rootaccess eq '0') {
@@ -1724,7 +1676,7 @@ sub create_user {
}
else {
notify($ERRORS{'DEBUG'}, 0, "user will be added to the Administrators group");
- $add_user_command .= " && net localgroup \"Administrators\" \"$username\" /ADD";
+ $add_user_command .= " && $system32_path/net.exe localgroup \"Administrators\" \"$username\" /ADD";
}
my ($add_user_exit_status, $add_user_output) = run_ssh_command($computer_node_name, $management_node_keys, $add_user_command, '', '', '1');
@@ -1766,6 +1718,7 @@ sub add_user_to_group {
my $management_node_keys = $self->data->get_management_node_keys();
my $computer_node_name = $self->data->get_computer_node_name();
+ my $system32_path = $self->get_system32_path() || return;
# Attempt to get the username from the arguments
# If no argument was supplied, use the user specified in the DataStructure
@@ -1776,8 +1729,8 @@ sub add_user_to_group {
return;
}
- # Attempt to add the user to the group using net localgroup
- my $localgroup_user_command = "net localgroup \"$group\" $username /ADD";
+ # Attempt to add the user to the group using net.exe localgroup
+ my $localgroup_user_command = "$system32_path/net.exe localgroup \"$group\" $username /ADD";
my ($localgroup_user_exit_status, $localgroup_user_output) = run_ssh_command($computer_node_name, $management_node_keys, $localgroup_user_command);
if (defined($localgroup_user_exit_status) && $localgroup_user_exit_status == 0) {
notify($ERRORS{'OK'}, 0, "added user $username to \"$group\" group on $computer_node_name");
@@ -1827,6 +1780,7 @@ sub delete_user {
my $management_node_keys = $self->data->get_management_node_keys();
my $computer_node_name = $self->data->get_computer_node_name();
+ my $system32_path = $self->get_system32_path() || return;
# Attempt to get the username from the arguments
# If no argument was supplied, use the user specified in the DataStructure
@@ -1838,7 +1792,7 @@ sub delete_user {
notify($ERRORS{'OK'}, 0, "attempting to delete user $username from $computer_node_name");
# Attempt to delete the user account
- my $delete_user_command = "net user $username /DELETE";
+ my $delete_user_command = "$system32_path/net.exe user $username /DELETE";
my ($delete_user_exit_status, $delete_user_output) = run_ssh_command($computer_node_name, $management_node_keys, $delete_user_command);
if (defined($delete_user_exit_status) && $delete_user_exit_status == 0) {
notify($ERRORS{'OK'}, 0, "deleted user $username from $computer_node_name");
@@ -1885,7 +1839,8 @@ sub set_password {
my $management_node_keys = $self->data->get_management_node_keys();
my $computer_node_name = $self->data->get_computer_node_name();
-
+ my $system32_path = $self->get_system32_path() || return;
+
# Attempt to get the username from the arguments
my $username = shift;
my $password = shift;
@@ -1906,7 +1861,7 @@ sub set_password {
# Attempt to set the password
notify($ERRORS{'DEBUG'}, 0, "setting password of $username to $password on $computer_node_name");
- my ($set_password_exit_status, $set_password_output) = run_ssh_command($computer_node_name, $management_node_keys, "net user $username '$password'");
+ my ($set_password_exit_status, $set_password_output) = run_ssh_command($computer_node_name, $management_node_keys, "$system32_path/net.exe user $username '$password'");
if ($set_password_exit_status == 0) {
notify($ERRORS{'OK'}, 0, "password changed to '$password' for user '$username' on $computer_node_name");
}
@@ -1930,7 +1885,7 @@ sub set_password {
# Attempt to change scheduled task passwords
notify($ERRORS{'DEBUG'}, 0, "changing passwords for scheduled tasks");
- my ($schtasks_query_exit_status, $schtasks_query_output) = run_ssh_command($computer_node_name, $management_node_keys, "schtasks.exe /Query /V /FO LIST", '', '', 0);
+ my ($schtasks_query_exit_status, $schtasks_query_output) = run_ssh_command($computer_node_name, $management_node_keys, "$system32_path/schtasks.exe /Query /V /FO LIST", '', '', 0);
if (defined($schtasks_query_exit_status) && $schtasks_query_exit_status == 0) {
notify($ERRORS{'DEBUG'}, 0, "queried scheduled tasks on $computer_node_name");
}
@@ -1958,7 +1913,7 @@ sub set_password {
# Loop through the scheduled tasks configured to run as the user, update the password
for my $task_name_to_update (@task_names_to_update) {
- my $schtasks_command = "schtasks.exe /Change /RU \"$username\" /RP \"$password\" /TN \"$task_name_to_update\"";
+ my $schtasks_command = "$system32_path/schtasks.exe /Change /RU \"$username\" /RP \"$password\" /TN \"$task_name_to_update\"";
my ($schtasks_change_exit_status, $schtasks_change_output) = run_ssh_command($computer_node_name, $management_node_keys, $schtasks_command, '', '', 0);
if (!defined($schtasks_change_output)) {
notify($ERRORS{'WARNING'}, 0, "failed to run ssh command to change password for scheduled task: $task_name_to_update");
@@ -2005,6 +1960,7 @@ sub enable_user {
my $management_node_keys = $self->data->get_management_node_keys();
my $computer_node_name = $self->data->get_computer_node_name();
+ my $system32_path = $self->get_system32_path() || return;
# Attempt to get the username from the arguments
my $username = shift;
@@ -2022,7 +1978,7 @@ sub enable_user {
# Attempt to enable the user account (set ACTIVE=YES)
notify($ERRORS{'DEBUG'}, 0, "enabling user $username on $computer_node_name");
- my ($enable_exit_status, $enable_output) = run_ssh_command($computer_node_name, $management_node_keys, "net user $username /ACTIVE:YES");
+ my ($enable_exit_status, $enable_output) = run_ssh_command($computer_node_name, $management_node_keys, "$system32_path/net.exe user $username /ACTIVE:YES");
if ($enable_exit_status == 0) {
notify($ERRORS{'OK'}, 0, "user $username enabled on $computer_node_name");
}
@@ -2057,10 +2013,11 @@ sub disable_pagefile {
my $management_node_keys = $self->data->get_management_node_keys();
my $computer_node_name = $self->data->get_computer_node_name();
-
+ my $system32_path = $self->get_system32_path() || return;
+
# Set the registry key to blank
my $memory_management_key = 'HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management';
- my $reg_add_command = $self->get_system32_path() . '/reg.exe add "' . $memory_management_key . '" /v PagingFiles /d "" /t REG_MULTI_SZ /f';
+ my $reg_add_command = $system32_path . '/reg.exe add "' . $memory_management_key . '" /v PagingFiles /d "" /t REG_MULTI_SZ /f';
my ($reg_add_exit_status, $reg_add_output) = run_ssh_command($computer_node_name, $management_node_keys, $reg_add_command, '', '', 1);
if (defined($reg_add_exit_status) && $reg_add_exit_status == 0) {
notify($ERRORS{'OK'}, 0, "set registry key to disable pagefile");
@@ -2123,10 +2080,11 @@ sub enable_pagefile {
my $management_node_keys = $self->data->get_management_node_keys();
my $computer_node_name = $self->data->get_computer_node_name();
+ my $system32_path = $self->get_system32_path() || return;
my $memory_management_key = 'HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management';
- my $reg_add_command = $self->get_system32_path() . '/reg.exe add "' . $memory_management_key . '" /v PagingFiles /d "$SYSTEMDRIVE\\pagefile.sys 0 0" /t REG_MULTI_SZ /f';
+ my $reg_add_command = $system32_path . '/reg.exe add "' . $memory_management_key . '" /v PagingFiles /d "$SYSTEMDRIVE\\pagefile.sys 0 0" /t REG_MULTI_SZ /f';
my ($reg_add_exit_status, $reg_add_output) = run_ssh_command($computer_node_name, $management_node_keys, $reg_add_command, '', '', 1);
if (defined($reg_add_exit_status) && $reg_add_exit_status == 0) {
notify($ERRORS{'OK'}, 0, "set registry key to enable pagefile");
@@ -2371,9 +2329,35 @@ sub import_registry_string {
=head2 reg_query
- Parameters : registry key, registry value
- Returns :
- Description :
+ Parameters : $registry_key, $registry_value (optional)
+ Returns : If $registry_value argument is specified: scalar
+ If $registry_value argument is specified: hash reference
+ Description : Queries the registry on the Windows computer. The $registry_key
+ argument is required. The $registry_value argument is optional.
+
+ If $registry_value is specified, a scalar containing the value's
+ data is returned. The '(Default)' value's data is returned if the
+ $registry_value is either an empty string or exactly matches the
+ string '(Default)'.
+
+ If $registry_value is NOT specified, a hash reference containing
+ the keys's subkey names, values, and each value's data is
+ returned. The hash has 2 keys: 'subkeys', 'values'.
+
+ The 'subkeys' key contains an array reference. This array contains
+ the names of the key arguments subkeys.
+
+ The 'values' key contain a hash reference. The keys of this hash
+ are the names of the values that are set for the key argument.
+ Each of theses contains a 'type' and 'data' key containing the
+ registry value type and value data.
+
+ Example:
+ my $registry_data = $self->os->reg_query('HKLM/SYSTEM/CurrentControlSet/Services/NetBT/Parameters');
+ @{$registry_data->{subkeys}}[0] = 'Interfaces'
+ my @value_names = @{$registry_data->{values}};
+ $registry_data->{values}{$value_names[0]}{type} = 'REG_DWORD'
+ $registry_data->{values}{$value_names[0]}{data} = '123'
=cut
@@ -2386,45 +2370,149 @@ sub reg_query {
my $management_node_keys = $self->data->get_management_node_keys();
my $computer_node_name = $self->data->get_computer_node_name();
+ my $system32_path = $self->get_system32_path() || return;
# Get the arguments
- my $registry_key = shift;
- if (!defined($registry_key) || !$registry_key) {
+ my $key_argument = shift;
+ if (!defined($key_argument) || !$key_argument) {
notify($ERRORS{'WARNING'}, 0, "registry key was not passed correctly as an argument");
return;
}
+ my $value_argument = shift;
- my $registry_value = shift;
- if (!defined($registry_value) || !$registry_value) {
- notify($ERRORS{'WARNING'}, 0, "registry value was not passed correctly as an argument");
- return;
- }
+ # Replace forward slashes and double backslashes with a single backslashes
+ $key_argument =~ s/[\\\/]+/\\/g;
- # Replace forward slashes with backslashes in registry key
- $registry_key =~ s/\//\\\\/g;
+ # Removing trailing slashes
+ $key_argument =~ s/\\+$//g;
+
+ # Replace abbreviated key names so argument matches reg.exe output
+ $key_argument =~ s/^HKLM/HKEY_LOCAL_MACHINE/;
+ $key_argument =~ s/^HKCU/HKEY_CURRENT_USER/;
+ $key_argument =~ s/^HKCR/HKEY_CLASSES_ROOT/;
+ $key_argument =~ s/^HKU/HKEY_USERS/;
+ $key_argument =~ s/^HKCC/HKEY_CURRENT_CONFIG/;
+
+ # Assemble the reg.exe QUERY command
+ my $command .= "$system32_path/reg.exe QUERY \"$key_argument\" ";
+
+ if (!defined($value_argument)) {
+ # Do not add any switches
+ $command .= "/s";
+ }
+ elsif ($value_argument eq '(Default)') {
+ # Add /ve switch to query the default value
+ $command .= "/ve";
+ }
+ else {
+ # Escape slashes and double-quotes in the value argument
+ (my $value_argument_escaped = $value_argument) =~ s/([\\\"])/\\$1/g;
+
+ # Add /v switch to query a specific value
+ $command .= "/v \"$value_argument_escaped\"";
+ }
# Run reg.exe QUERY
- my $query_registry_command .= $self->get_system32_path() . "/reg.exe QUERY \"$registry_key\" /v \"$registry_value\"";
- my ($query_registry_exit_status, $query_registry_output) = run_ssh_command($computer_node_name, $management_node_keys, $query_registry_command, '', '', 1);
- if (defined($query_registry_exit_status) && $query_registry_exit_status == 0) {
- notify($ERRORS{'DEBUG'}, 0, "queried registry key: $registry_key, value: $registry_value, output:\n" . join("\n", @$query_registry_output));
+ my ($exit_status, $output) = run_ssh_command($computer_node_name, $management_node_keys, $command, '', '', 1);
+ if (!defined($output)) {
+ notify($ERRORS{'WARNING'}, 0, "failed to run SSH command to query registry key: $key_argument");
+ return;
}
- elsif ($query_registry_exit_status) {
- notify($ERRORS{'WARNING'}, 0, "failed to query registry key: $registry_key, value: $registry_value, exit status: $query_registry_exit_status, output:\n@{$query_registry_output}");
+ elsif (grep(/^Error:/, @$output)) {
+ my $message = "failed to query registry:\nkey: '$key_argument'\n";
+ $message .= "value: '$value_argument'\n" if defined($value_argument);
+ $message .= "command: '$command'\noutput:\n" . join("\n", @{$output});
+ notify($ERRORS{'WARNING'}, 0, $message);
return;
}
+
+ notify($ERRORS{'DEBUG'}, 0, "reg.exe QUERY output:\n" . join("\n", @$output));
+
+ # If value argument was specified, parse and return the data
+ if (defined($value_argument)) {
+ # Find the line containing the value information and parse it
+ my ($value, $type, $data) = map { $_ =~ /^\s+([^\t]+)\t(REG_\w+)\t?(.*)/ } @$output;
+ $value = '(Default)' if $value eq '<NO NAME>';
+ if ($type && defined($data)) {
+ $data = $self->reg_query_convert_data($type, $data);
+ notify($ERRORS{'DEBUG'}, 0, "retrieved registry data:\nkey: '$key_argument'\nvalue: '$value'\ntype: $type\ndata: '$data'");
+ return $data;
+ }
+ else {
+ notify($ERRORS{'WARNING'}, 0, "failed to retrieve registry data:\nkey: '$key_argument'\nvalue: '$value'\ncommand: '$command'\noutput:\n" . join("\n", @$output));
+ return;
+ }
+ }
else {
- notify($ERRORS{'WARNING'}, 0, "failed to run SSH command to query registry key: $registry_key, value: $registry_value");
+ # Value argument was not specified, construct a hash containing the contents of the key
+ my %registry_hash;
+
+ my $key;
+ for my $line (@$output) {
+ if ($line =~ /^HKEY/) {
+ ## Don't add the key being queried to the result, only add subkeys
+ #next if ($line eq $key_argument);
+
+ $key = $line;
+ $registry_hash{$key} = {};
+ next;
+ }
+ elsif ($line =~ /^\s+([^\t]+)\t(REG_\w+)\t(.*)/) {
+ my ($value, $type, $data) = ($1, $2, $3);
+ $value = '(Default)' if $value eq '<NO NAME>';
+ $data = $self->reg_query_convert_data($type, $data);
+
+ #$registry_hash{$key}{$value}{type} = $type;
+ $registry_hash{$key}{$value} = $data;
+ }
+ elsif ($line =~ /^!/) {
+ # Ignore lines beginning with '!'
+ next;
+ }
+ else {
+ notify($ERRORS{'WARNING'}, 0, "unexpected output in line: '" . string_to_ascii($line) . "'");
+ }
+ }
+
+ notify($ERRORS{'DEBUG'}, 0, "retrieved registry data:\n" . format_data(\%registry_hash));
+ return \%registry_hash;
+ }
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 reg_query_convert_data
+
+ Parameters : $type, $data
+ Returns : scalar
+ Description :
+
+=cut
+
+sub reg_query_convert_data {
+ my $self = shift;
+ if (ref($self) !~ /windows/i) {
+ notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
return;
}
- my ($output_line) = grep(/^\s*$registry_value/i, @$query_registry_output);
- #notify($ERRORS{'DEBUG'}, 0, "output line: $output_line");
+ my ($type, $data) = @_;
+ if (!$type || !defined($data)) {
+ notify($ERRORS{'WARNING'}, 0, "registry data type and data value arguments were not specified");
+ return;
+ }
- my ($output_value, $output_type, $output_data) = $output_line =~ /\s*($registry_value)\s+([\w_]+)\s+(.*)/;
- notify($ERRORS{'DEBUG'}, 0, "output:\nvalue: '$output_value'\ntype: '$output_type'\ndata: '$output_data'");
+ if ($type eq 'REG_DWORD') {
+ # Convert the hex value to decimal
+ $data = hex($data);
+ }
+ if ($type eq 'REG_MULTI_SZ') {
+ # Split data into an array, data values are separated in the output by '\0'
+ my @data_values = split(/\\0/, $data);
+ $data = \@data_values;
+ }
- return $output_data;
+ return $data;
}
#/////////////////////////////////////////////////////////////////////////////
@@ -2447,6 +2535,7 @@ sub reg_add {
my $management_node_keys = $self->data->get_management_node_keys();
my $computer_node_name = $self->data->get_computer_node_name();
+ my $system32_path = $self->get_system32_path() || return;
# Get the arguments
my $registry_key = shift;
@@ -2490,7 +2579,7 @@ sub reg_add {
$registry_key =~ s/\//\\\\/g;
# Run reg.exe ADD
- my $add_registry_command = $self->get_system32_path() . "/reg.exe ADD \"$registry_key\" $value_parameter /t $registry_type /d \"$registry_data\" /f";
+ my $add_registry_command = $system32_path . "/reg.exe ADD \"$registry_key\" $value_parameter /t $registry_type /d \"$registry_data\" /f";
my ($add_registry_exit_status, $add_registry_output) = run_ssh_command($computer_node_name, $management_node_keys, $add_registry_command, '', '', 1);
if (defined($add_registry_exit_status) && $add_registry_exit_status == 0) {
notify($ERRORS{'DEBUG'}, 0, "added registry key: $registry_key, output:\n" . join("\n", @$add_registry_output));
@@ -2526,6 +2615,7 @@ sub reg_delete {
my $management_node_keys = $self->data->get_management_node_keys();
my $computer_node_name = $self->data->get_computer_node_name();
+ my $system32_path = $self->get_system32_path() || return;
# Get the arguments
my $registry_key = shift;
@@ -2541,10 +2631,10 @@ sub reg_delete {
# Run reg.exe DELETE
my $delete_registry_command;
if ($registry_value) {
- $delete_registry_command = $self->get_system32_path() . "/reg.exe DELETE \"$registry_key\" /v \"$registry_value\" /f";
+ $delete_registry_command = $system32_path . "/reg.exe DELETE \"$registry_key\" /v \"$registry_value\" /f";
}
else {
- $delete_registry_command = $self->get_system32_path() . "/reg.exe DELETE \"$registry_key\" /f";
+ $delete_registry_command = $system32_path . "/reg.exe DELETE \"$registry_key\" /f";
$registry_value = '*';
}
my ($delete_registry_exit_status, $delete_registry_output) = run_ssh_command($computer_node_name, $management_node_keys, $delete_registry_command, '', '', 1);
@@ -2582,6 +2672,7 @@ sub reg_import {
my $management_node_keys = $self->data->get_management_node_keys();
my $computer_node_name = $self->data->get_computer_node_name();
+ my $system32_path = $self->get_system32_path() || return;
# Get the registry file path argument
my $registry_file_path = shift;
@@ -2591,7 +2682,7 @@ sub reg_import {
}
# Run reg.exe IMPORT
- my $import_registry_command .= $self->get_system32_path() . "/reg.exe IMPORT $registry_file_path";
+ my $import_registry_command .= $system32_path . "/reg.exe IMPORT $registry_file_path";
my ($import_registry_exit_status, $import_registry_output) = run_ssh_command($computer_node_name, $management_node_keys, $import_registry_command, '', '', 1);
if (defined($import_registry_exit_status) && $import_registry_exit_status == 0) {
notify($ERRORS{'DEBUG'}, 0, "imported registry file: $registry_file_path");
@@ -2627,7 +2718,8 @@ sub add_hklm_run_registry_key {
my $management_node_keys = $self->data->get_management_node_keys();
my $computer_node_name = $self->data->get_computer_node_name();
-
+ my $system32_path = $self->get_system32_path() || return;
+
my $command_name = shift;
my $command = shift;
@@ -2671,7 +2763,7 @@ EOF
}
# Attempt to query the registry key to make sure it was added
- my $reg_query_command = $self->get_system32_path() . '/reg.exe query "HKLM\\SOFTWARE\\Microsoft\Windows\\\CurrentVersion\\Run"';
+ my $reg_query_command = $system32_path . '/reg.exe query "HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run"';
my ($reg_query_exit_status, $reg_query_output) = run_ssh_command($computer_node_name, $management_node_keys, $reg_query_command, '', '', 1);
if (defined($reg_query_exit_status) && $reg_query_exit_status == 0) {
notify($ERRORS{'DEBUG'}, 0, "queried '$command_name' registry key:\n" . join("\n", @{$reg_query_output}));
@@ -2707,7 +2799,8 @@ sub delete_hklm_run_registry_key {
my $management_node_keys = $self->data->get_management_node_keys();
my $computer_node_name = $self->data->get_computer_node_name();
-
+ my $system32_path = $self->get_system32_path() || return;
+
my $key_name = shift;
# Make sure argument was supplied
@@ -2717,7 +2810,7 @@ sub delete_hklm_run_registry_key {
}
# Attempt to query the registry key to make sure it was added
- my $reg_delete_command = $self->get_system32_path() . '/reg.exe delete "HKLM\\SOFTWARE\\Microsoft\Windows\\\CurrentVersion\\Run" /v "' . $key_name . '" /F';
+ my $reg_delete_command = $system32_path . '/reg.exe delete "HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run" /v "' . $key_name . '" /F';
my ($reg_delete_exit_status, $reg_delete_output) = run_ssh_command($computer_node_name, $management_node_keys, $reg_delete_command, '', '', 1);
if (defined($reg_delete_exit_status) && $reg_delete_exit_status == 0) {
notify($ERRORS{'OK'}, 0, "deleted '$key_name' run registry key:\n" . join("\n", @{$reg_delete_output}));
@@ -2756,11 +2849,12 @@ sub delete_scheduled_task {
my $management_node_keys = $self->data->get_management_node_keys();
my $computer_node_name = $self->data->get_computer_node_name();
-
+ my $system32_path = $self->get_system32_path() || return;
+
my $task_name = shift;
# Run schtasks.exe to delete any existing task
- my $delete_task_command = 'schtasks.exe /Delete /F /TN "' . $task_name . '"';
+ my $delete_task_command = "$system32_path/schtasks.exe /Delete /F /TN \"$task_name\"";
my ($delete_task_exit_status, $delete_task_output) = run_ssh_command($computer_node_name, $management_node_keys, $delete_task_command);
if (defined($delete_task_exit_status) && $delete_task_exit_status == 0) {
notify($ERRORS{'OK'}, 0, "deleted existing scheduled task '$task_name' on $computer_node_name");
@@ -2799,7 +2893,8 @@ sub create_startup_scheduled_task {
my $management_node_keys = $self->data->get_management_node_keys();
my $computer_node_name = $self->data->get_computer_node_name();
-
+ my $system32_path = $self->get_system32_path() || return;
+
my $task_name = shift;
my $task_command = shift;
my $task_user = shift;
@@ -2830,7 +2925,7 @@ sub create_startup_scheduled_task {
# Run schtasks.exe to add the task
# Occasionally see this error even though it schtasks.exe returns exit status 0:
# WARNING: The Scheduled task "System Startup Script" has been created, but may not run because the account information could not be set.
- my $create_task_command = "schtasks.exe /Create /RU \"$task_user\" /RP \"$task_password\" /SC ONSTART /TN \"$task_name\" /TR \"$task_command\"";
+ my $create_task_command = "$system32_path/schtasks.exe /Create /RU \"$task_user\" /RP \"$task_password\" /SC ONSTART /TN \"$task_name\" /TR \"$task_command\"";
my ($create_task_exit_status, $create_task_output) = run_ssh_command($computer_node_name, $management_node_keys, $create_task_command);
if (defined($create_task_output) && grep(/could not be set/i, @{$create_task_output})) {
notify($ERRORS{'WARNING'}, 0, "created scheduled task '$task_name' on $computer_node_name but error occurred: " . join("\n", @{$create_task_output}));
@@ -2955,7 +3050,8 @@ sub create_eventlog_entry {
my $management_node_keys = $self->data->get_management_node_keys();
my $computer_node_name = $self->data->get_computer_node_name();
-
+ my $system32_path = $self->get_system32_path() || return;
+
my $message = shift;
# Make sure the message was passed as an argument
@@ -2965,7 +3061,7 @@ sub create_eventlog_entry {
}
# Run eventcreate.exe to create an event log entry
- my $eventcreate_command = $self->get_system32_path() . '/eventcreate.exe /T INFORMATION /L APPLICATION /SO VCL /ID 555 /D "' . $message . '"';
+ my $eventcreate_command = $system32_path . '/eventcreate.exe /T INFORMATION /L APPLICATION /SO VCL /ID 555 /D "' . $message . '"';
my ($eventcreate_exit_status, $eventcreate_output) = run_ssh_command($computer_node_name, $management_node_keys, $eventcreate_command);
if (defined($eventcreate_exit_status) && $eventcreate_exit_status == 0) {
notify($ERRORS{'OK'}, 0, "created event log entry on $computer_node_name: $message");
@@ -3001,7 +3097,8 @@ sub reboot {
my $management_node_keys = $self->data->get_management_node_keys();
my $computer_node_name = $self->data->get_computer_node_name();
-
+ my $system32_path = $self->get_system32_path() || return;
+
# Check if an argument was supplied
my $wait_for_reboot = shift;
if (!defined($wait_for_reboot) || $wait_for_reboot !~ /0/) {
@@ -3037,7 +3134,7 @@ sub reboot {
}
# Initiate the shutdown.exe command to reboot the computer
- my $shutdown_command = $self->get_system32_path() . "/shutdown.exe -r -t 0 -f";
+ my $shutdown_command = $system32_path . "/shutdown.exe -r -t 0 -f";
my ($shutdown_exit_status, $shutdown_output) = run_ssh_command($computer_node_name, $management_node_keys, $shutdown_command);
if (defined($shutdown_exit_status) && $shutdown_exit_status == 0) {
notify($ERRORS{'OK'}, 0, "executed reboot command on $computer_node_name");
@@ -3177,9 +3274,9 @@ sub shutdown {
my $management_node_keys = $self->data->get_management_node_keys();
my $computer_node_name = $self->data->get_computer_node_name();
+ my $system32_path = $self->get_system32_path() || return;
- my $system32_path = $self->get_system32_path();
- my $shutdown_command = "/bin/cygstart.exe cmd.exe /c \"";
+ my $shutdown_command = "/bin/cygstart.exe $system32_path/cmd.exe /c \"";
if ($disable_dhcp) {
notify($ERRORS{'DEBUG'}, 0, "enabling DHCP and shutting down $computer_node_name");
@@ -3233,22 +3330,21 @@ sub shutdown {
}
# Wait maximum of 3 minutes for the computer to become unresponsive
- if ($self->wait_for_no_ping(180)) {
- notify($ERRORS{'OK'}, 0, "attempt $attempt_count/$attempt_limit: computer has become unresponsive after shutdown command was issued");
- return 1;
- }
- else {
+ if (!$self->wait_for_no_ping(180)) {
# Computer never stopped responding to ping
- notify($ERRORS{'WARNING'}, 0, "$computer_node_name did not become unresponsive after shutdown command was issued, attempting power off");
+ notify($ERRORS{'WARNING'}, 0, "$computer_node_name never became unresponsive to ping after shutdown command was issued");
+ return;
}
- # Call provisioning module's power_off() subroutine
- notify($ERRORS{'OK'}, 0, "failed to shutdown $computer_node_name using shutdown.exe, calling provisioning module's power_off subroutine");
- if ($self->provisioner->power_off()) {
- notify($ERRORS{'OK'}, 0, "powered off $computer_node_name");
+ # Wait maximum of 5 minutes for computer to power off
+ my $power_off = $self->provisioner->wait_for_power_off(300);
+ if (!defined($power_off)) {
+ # wait_for_power_off result will be undefined if the provisioning module doesn't implement a power_status subroutine
+ notify($ERRORS{'OK'}, 0, "unable to determine power status of $computer_node_name from provisioning module, sleeping 1 minute to allow computer time to shutdown");
+ sleep 60;
}
- else {
- notify($ERRORS{'WARNING'}, 0, "failed to power off $computer_node_name");
+ elsif (!$power_off) {
+ notify($ERRORS{'WARNING'}, 0, "$computer_node_name never powered off");
return;
}
@@ -3274,7 +3370,8 @@ sub set_service_startup_mode {
my $management_node_keys = $self->data->get_management_node_keys();
my $computer_node_name = $self->data->get_computer_node_name();
-
+ my $system32_path = $self->get_system32_path() || return;
+
my $service_name = shift;
my $startup_mode = shift;
@@ -3294,7 +3391,7 @@ sub set_service_startup_mode {
$startup_mode = "demand" if ($startup_mode eq "manual");
# Use sc.exe to change the start mode
- my $service_startup_command = $self->get_system32_path() . '/sc.exe config ' . "$service_name start= $startup_mode";
+ my $service_startup_command = $system32_path . '/sc.exe config ' . "$service_name start= $startup_mode";
my ($service_startup_exit_status, $service_startup_output) = run_ssh_command($computer_node_name, $management_node_keys, $service_startup_command);
if (defined($service_startup_output) && grep(/service does not exist/, @$service_startup_output)) {
notify($ERRORS{'WARNING'}, 0, "$service_name service startup mode not set because service does not exist");
@@ -3334,10 +3431,11 @@ sub defragment_hard_drive {
my $management_node_keys = $self->data->get_management_node_keys();
my $computer_node_name = $self->data->get_computer_node_name();
-
+ my $system32_path = $self->get_system32_path() || return;
+
# Defragment the hard drive
notify($ERRORS{'OK'}, 0, "beginning to defragment the hard drive on $computer_node_name");
- my ($defrag_exit_status, $defrag_output) = run_ssh_command($computer_node_name, $management_node_keys, $self->get_system32_path() . '/defrag.exe $SYSTEMDRIVE -v');
+ my ($defrag_exit_status, $defrag_output) = run_ssh_command($computer_node_name, $management_node_keys, $system32_path . '/defrag.exe $SYSTEMDRIVE -v');
if (defined($defrag_exit_status) && $defrag_exit_status == 0) {
notify($ERRORS{'OK'}, 0, "hard drive defragmentation complete on $computer_node_name");
return 1;
@@ -3438,7 +3536,8 @@ sub set_service_credentials {
my $management_node_keys = $self->data->get_management_node_keys();
my $computer_node_name = $self->data->get_computer_node_name();
-
+ my $system32_path = $self->get_system32_path() || return;
+
# Attempt to get the username from the arguments
my $service_name = shift;
my $username = shift;
@@ -3451,7 +3550,7 @@ sub set_service_credentials {
}
# Attempt to set the service logon user name and password
- my $service_logon_command = $self->get_system32_path() . '/sc.exe config ' . $service_name . ' obj= ".\\' . $username . '" password= "' . $password . '"';
+ my $service_logon_command = $system32_path . '/sc.exe config ' . $service_name . ' obj= ".\\' . $username . '" password= "' . $password . '"';
my ($service_logon_exit_status, $service_logon_output) = run_ssh_command($computer_node_name, $management_node_keys, $service_logon_command);
if (defined($service_logon_exit_status) && $service_logon_exit_status == 0) {
notify($ERRORS{'OK'}, 0, "changed logon credentials for '$service_name' service to $username ($password) on $computer_node_name");
@@ -3487,9 +3586,10 @@ sub get_service_list {
my $management_node_keys = $self->data->get_management_node_keys();
my $computer_node_name = $self->data->get_computer_node_name();
-
+ my $system32_path = $self->get_system32_path() || return;
+
# Attempt to delete the user account
- my $sc_query_command = $self->get_system32_path() . "/sc.exe query | grep SERVICE_NAME | cut --fields=2 --delimiter=' '";
+ my $sc_query_command = $system32_path . "/sc.exe query | grep SERVICE_NAME | cut --fields=2 --delimiter=' '";
my ($sc_query_exit_status, $sc_query_output) = run_ssh_command($computer_node_name, $management_node_keys, $sc_query_command);
if (defined($sc_query_exit_status) && $sc_query_exit_status == 0) {
notify($ERRORS{'OK'}, 0, "retrieved service list on $computer_node_name");
@@ -3527,7 +3627,8 @@ sub get_services_using_login_id {
my $management_node_keys = $self->data->get_management_node_keys();
my $computer_node_name = $self->data->get_computer_node_name();
-
+ my $system32_path = $self->get_system32_path() || return;
+
my $login_id = shift;
if (!$login_id) {
notify($ERRORS{'WARNING'}, 0, "unable to get services using login id, login id argument was not passed correctly");
@@ -3544,7 +3645,7 @@ sub get_services_using_login_id {
my @services_using_login_id;
for my $service_name (@service_list) {
# Attempt to get the service start name using sc.exe qc
- my $sc_qc_command = $self->get_system32_path() . "/sc.exe qc $service_name | grep SERVICE_START_NAME | cut --fields=2 --delimiter='\\'";
+ my $sc_qc_command = $system32_path . "/sc.exe qc $service_name | grep SERVICE_START_NAME | cut --fields=2 --delimiter='\\'";
my ($sc_qc_exit_status, $sc_qc_output) = run_ssh_command($computer_node_name, $management_node_keys, $sc_qc_command);
if (defined($sc_qc_exit_status) && $sc_qc_exit_status == 0) {
notify($ERRORS{'OK'}, 0, "retrieved $service_name service start name from $computer_node_name");
@@ -3586,7 +3687,8 @@ sub disable_scheduled_task {
my $management_node_keys = $self->data->get_management_node_keys();
my $computer_node_name = $self->data->get_computer_node_name();
-
+ my $system32_path = $self->get_system32_path() || return;
+
# Attempt to get the task name from the arguments
my $task_name = shift;
if (!$task_name) {
@@ -3595,7 +3697,7 @@ sub disable_scheduled_task {
}
# Attempt to delete the user account
- my $schtasks_command = $self->get_system32_path() . '/schtasks.exe /Change /DISABLE /TN "' . $task_name . '"';
+ my $schtasks_command = $system32_path . '/schtasks.exe /Change /DISABLE /TN "' . $task_name . '"';
my ($schtasks_exit_status, $schtasks_output) = run_ssh_command($computer_node_name, $management_node_keys, $schtasks_command, '', '', 1);
if (!defined($schtasks_output)) {
notify($ERRORS{'WARNING'}, 0, "failed to run ssh command to disable $task_name scheduled task on $computer_node_name");
@@ -3666,9 +3768,10 @@ sub get_scheduled_tasks {
my $management_node_keys = $self->data->get_management_node_keys();
my $computer_node_name = $self->data->get_computer_node_name();
-
+ my $system32_path = $self->get_system32_path() || return;
+
# Attempt to retrieve scheduled task information
- my $schtasks_command = $self->get_system32_path() . '/schtasks.exe /Query /NH /V /FO CSV';
+ my $schtasks_command = $system32_path . '/schtasks.exe /Query /NH /V /FO CSV';
my ($schtasks_exit_status, $schtasks_output) = run_ssh_command($computer_node_name, $management_node_keys, $schtasks_command);
if (defined($schtasks_exit_status) && $schtasks_exit_status == 0) {
notify($ERRORS{'OK'}, 0, "retrieved scheduled task information");
@@ -3747,7 +3850,8 @@ sub disable_dynamic_dns {
my $management_node_keys = $self->data->get_management_node_keys();
my $computer_node_name = $self->data->get_computer_node_name();
-
+ my $system32_path = $self->get_system32_path() || return;
+
my $registry_string .= <<"EOF";
Windows Registry Editor Version 5.00
@@ -3782,13 +3886,13 @@ EOF
# Assemble netsh.exe commands to disable DNS registration
my $netsh_command;
- $netsh_command .= "netsh.exe interface ip set dns";
+ $netsh_command .= "$system32_path/netsh.exe interface ip set dns";
$netsh_command .= " name = \"$public_interface_name\"";
$netsh_command .= " source = dhcp";
$netsh_command .= " register = none";
$netsh_command .= " ;";
- $netsh_command .= "netsh.exe interface ip set dns";
+ $netsh_command .= "$system32_path/netsh.exe interface ip set dns";
$netsh_command .= " name = \"$private_interface_name\"";
$netsh_command .= " source = dhcp";
$netsh_command .= " register = none";
@@ -3832,61 +3936,25 @@ sub disable_netbios {
my $computer_node_name = $self->data->get_computer_node_name();
# Attempt to query the registry for the NetBT service parameters
- my $reg_query_command = $self->get_system32_path() . '/reg.exe query "HKLM\SYSTEM\CurrentControlSet\Services\NetBT\Parameters\Interfaces" /s';
- my ($reg_query_exit_status, $reg_query_output) = run_ssh_command($computer_node_name, $management_node_keys, $reg_query_command, '', '', 1);
- if (defined($reg_query_exit_status) && $reg_query_exit_status == 0) {
- notify($ERRORS{'DEBUG'}, 0, "queried NetBT parameters registry keys");
- }
- elsif (defined($reg_query_exit_status)) {
- notify($ERRORS{'WARNING'}, 0, "failed to query NetBT parameters registry keys, exit status: $reg_query_exit_status, output:\n@{$reg_query_output}");
- return 0;
- }
- else {
- notify($ERRORS{'WARNING'}, 0, "failed to run ssh command to query NetBT parameters registry keys");
+ my $interface_registry_data = $self->reg_query('HKLM/SYSTEM/CurrentControlSet/Services/NetBT/Parameters/Interfaces');
+ if (!$interface_registry_data) {
+ notify($ERRORS{'WARNING'}, 0, "failed to query registry to determine NetBT network interface strings");
return;
}
-
- # Loop through the interfaces found, disable NetBIOS for any interface which has a NetbiosOptions key
- my $interface_key;
- for my $query_line (@{$reg_query_output}) {
- # Check if line is an interface key
- if ($query_line =~ /^(HKEY.*Tcpip.*})/i) {
- $interface_key = $1;
- next;
+
+ my @interface_keys = grep(/Tcpip_/i, keys %{$interface_registry_data});
+ notify($ERRORS{'DEBUG'}, 0, "retrieved NetBT interface keys:\n" . join("\n", @interface_keys));
+
+ for my $interface_key (@interface_keys) {
+ my $netbios_options = $interface_registry_data->{$interface_key}{NetbiosOptions};
+
+ next if !defined($netbios_options);
+ notify($ERRORS{'DEBUG'}, 0, "$interface_key: NetbiosOptions = $netbios_options");
+
+ if (!$self->reg_add($interface_key, 'NetbiosOptions', 'REG_DWORD', 2)) {
+ notify($ERRORS{'WARNING'}, 0, "failed to set NetbiosOptions = 2 under interface key: $interface_key");
+ return;
}
-
- if ($query_line =~ /NetbiosOptions/i) {
- # Attempt to set the NetbiosOptions key
- my $reg_add_command = $self->get_system32_path() . '/reg.exe add "' . $interface_key . '" /v NetbiosOptions /d 2 /t REG_DWORD /f';
- my ($reg_add_exit_status, $reg_add_output) = run_ssh_command($computer_node_name, $management_node_keys, $reg_add_command, '', '', 1);
- if (defined($reg_add_exit_status) && $reg_add_exit_status == 0) {
- notify($ERRORS{'OK'}, 0, "disabled NetBIOS under: $interface_key");
- }
- elsif (defined($reg_add_exit_status)) {
- notify($ERRORS{'WARNING'}, 0, "failed to disable NetBIOS under: $interface_key, exit status: $reg_add_exit_status, output:\n@{$reg_add_output}");
- return 0;
- }
- else {
- notify($ERRORS{'WARNING'}, 0, "failed to run ssh command to disable NetBIOS under: $interface_key");
- return;
- }
- } ## end if ($query_line =~ /NetbiosOptions/i)
- } ## end for my $query_line (@{$reg_query_output})
-
- # Attempt to stop the TCP/IP NetBIOS Helper service
- if ($self->stop_service('LmHosts')) {
- notify($ERRORS{'OK'}, 0, "TCP/IP NetBIOS Helper (LmHosts) service is stopped");
- }
- else {
- notify($ERRORS{'WARNING'}, 0, "unable to stop the TCP/IP NetBIOS Helper (LmHosts) service");
- }
-
- # Attempt to disable the TCP/IP NetBIOS Helper service
- if ($self->set_service_startup_mode('LmHosts', 'disabled')) {
- notify($ERRORS{'OK'}, 0, "TCP/IP NetBIOS Helper (LmHosts) service is disabled");
- }
- else {
- notify($ERRORS{'WARNING'}, 0, "failed to disable the TCP/IP NetBIOS Helper (LmHosts) service");
}
return 1;
@@ -3957,12 +4025,13 @@ sub set_my_computer_name {
my $management_node_keys = $self->data->get_management_node_keys();
my $computer_node_name = $self->data->get_computer_node_name();
+ my $system32_path = $self->get_system32_path() || return;
my $image_prettyname = $self->data->get_image_prettyname();
-
+
my $value = shift;
$value = $image_prettyname if !$value;
- my $add_registry_command .= $self->get_system32_path() . "/reg.exe add \"HKCR\\CLSID\\{20D04FE0-3AEA-1069-A2D8-08002B30309D}\" /v LocalizedString /t REG_EXPAND_SZ /d \"$value\" /f";
+ my $add_registry_command .= $system32_path . "/reg.exe add \"HKCR\\CLSID\\{20D04FE0-3AEA-1069-A2D8-08002B30309D}\" /v LocalizedString /t REG_EXPAND_SZ /d \"$value\" /f";
my ($add_registry_exit_status, $add_registry_output) = run_ssh_command($computer_node_name, $management_node_keys, $add_registry_command, '', '', 1);
if (defined($add_registry_exit_status) && $add_registry_exit_status == 0) {
notify($ERRORS{'OK'}, 0, "my computer name changed to '$value'");
@@ -3996,11 +4065,12 @@ sub firewall_enable_ping {
return;
}
- my $management_node_keys = $self->data->get_management_node_keys();
- my $computer_node_name = $self->data->get_computer_node_name();
+ my $management_node_keys = $self->data->get_management_node_keys();
+ my $computer_node_name = $self->data->get_computer_node_name();
+ my $system32_path = $self->get_system32_path() || return;
my $netsh_command;
- $netsh_command .= "netsh.exe firewall set icmpsetting";
+ $netsh_command .= "$system32_path/netsh.exe firewall set icmpsetting";
$netsh_command .= " type = 8";
$netsh_command .= " mode = ENABLE";
$netsh_command .= " profile = ALL";
@@ -4040,8 +4110,9 @@ sub firewall_enable_ping_private {
return;
}
- my $management_node_keys = $self->data->get_management_node_keys();
- my $computer_node_name = $self->data->get_computer_node_name();
+ my $management_node_keys = $self->data->get_management_node_keys();
+ my $computer_node_name = $self->data->get_computer_node_name();
+ my $system32_path = $self->get_system32_path() || return;
my $netsh_command;
@@ -4051,7 +4122,7 @@ sub firewall_enable_ping_private {
if ($public_interface_name) {
notify($ERRORS{'DEBUG'}, 0, "ping will be disabled on public interface: $public_interface_name");
- $netsh_command .= "netsh.exe firewall set icmpsetting";
+ $netsh_command .= "$system32_path/netsh.exe firewall set icmpsetting";
$netsh_command .= " type = 8";
$netsh_command .= " mode = DISABLE";
$netsh_command .= " interface = \"$public_interface_name\"";
@@ -4067,13 +4138,13 @@ sub firewall_enable_ping_private {
if ($private_interface_name) {
notify($ERRORS{'DEBUG'}, 0, "ping will be enabled on private interface: $private_interface_name");
- $netsh_command .= "netsh.exe firewall set icmpsetting";
+ $netsh_command .= "$system32_path/netsh.exe firewall set icmpsetting";
$netsh_command .= " type = 8";
$netsh_command .= " mode = DISABLE";
$netsh_command .= " profile = ALL";
$netsh_command .= ' ;';
- $netsh_command .= "netsh.exe firewall set icmpsetting";
+ $netsh_command .= "$system32_path/netsh.exe firewall set icmpsetting";
$netsh_command .= " type = 8";
$netsh_command .= " mode = ENABLE";
$netsh_command .= " interface = \"$private_interface_name\"";
@@ -4081,7 +4152,7 @@ sub firewall_enable_ping_private {
else {
notify($ERRORS{'WARNING'}, 0, "private interface name could not be determined, ping will be enabled for all profiles");
- $netsh_command .= "netsh.exe firewall set icmpsetting";
+ $netsh_command .= "$system32_path/netsh.exe firewall set icmpsetting";
$netsh_command .= " type = 8";
$netsh_command .= " mode = ENABLE";
$netsh_command .= " profile = ALL";
@@ -4123,8 +4194,9 @@ sub firewall_disable_ping {
return;
}
- my $management_node_keys = $self->data->get_management_node_keys();
- my $computer_node_name = $self->data->get_computer_node_name();
+ my $management_node_keys = $self->data->get_management_node_keys();
+ my $computer_node_name = $self->data->get_computer_node_name();
+ my $system32_path = $self->get_system32_path() || return;
my $netsh_command;
@@ -4134,7 +4206,7 @@ sub firewall_disable_ping {
if ($private_interface_name) {
notify($ERRORS{'DEBUG'}, 0, "retrieved private interface name: $private_interface_name");
- $netsh_command .= "netsh.exe firewall set icmpsetting";
+ $netsh_command .= "$system32_path/netsh.exe firewall set icmpsetting";
$netsh_command .= " type = 8";
$netsh_command .= " mode = DISABLE";
$netsh_command .= " interface = \"$private_interface_name\"";
@@ -4150,7 +4222,7 @@ sub firewall_disable_ping {
if ($public_interface_name) {
notify($ERRORS{'DEBUG'}, 0, "retrieved public interface name: $public_interface_name");
- $netsh_command .= "netsh.exe firewall set icmpsetting";
+ $netsh_command .= "$system32_path/netsh.exe firewall set icmpsetting";
$netsh_command .= " type = 8";
$netsh_command .= " mode = DISABLE";
$netsh_command .= " interface = \"$public_interface_name\"";
@@ -4161,7 +4233,7 @@ sub firewall_disable_ping {
}
# Add command to disable ping for all profiles
- $netsh_command .= "netsh.exe firewall set icmpsetting";
+ $netsh_command .= "$system32_path/netsh.exe firewall set icmpsetting";
$netsh_command .= " type = 8";
$netsh_command .= " mode = DISABLE";
$netsh_command .= " profile = ALL";
@@ -4204,9 +4276,10 @@ sub firewall_enable_ssh {
# Check if the remote IP was passed correctly as an argument
my $remote_ip = shift;
- my $management_node_keys = $self->data->get_management_node_keys();
- my $computer_node_name = $self->data->get_computer_node_name();
-
+ my $management_node_keys = $self->data->get_management_node_keys();
+ my $computer_node_name = $self->data->get_computer_node_name();
+ my $system32_path = $self->get_system32_path() || return;
+
my $netsh_command;
# Get the public interface name
@@ -4215,7 +4288,7 @@ sub firewall_enable_ssh {
if ($public_interface_name) {
notify($ERRORS{'DEBUG'}, 0, "SSH will be disabled on public interface: $public_interface_name");
- $netsh_command .= "netsh.exe firewall delete portopening";
+ $netsh_command .= "$system32_path/netsh.exe firewall delete portopening";
$netsh_command .= " protocol = TCP";
$netsh_command .= " port = 22";
$netsh_command .= " interface = \"$public_interface_name\"";
@@ -4231,7 +4304,7 @@ sub firewall_enable_ssh {
if ($private_interface_name) {
notify($ERRORS{'DEBUG'}, 0, "SSH will be disabled on private interface: $private_interface_name");
- $netsh_command .= "netsh.exe firewall delete portopening";
+ $netsh_command .= "$system32_path/netsh.exe firewall delete portopening";
$netsh_command .= " protocol = TCP";
$netsh_command .= " port = 22";
$netsh_command .= " interface = \"$private_interface_name\"";
@@ -4241,7 +4314,7 @@ sub firewall_enable_ssh {
notify($ERRORS{'WARNING'}, 0, "SSH will not be disabled on private interface because private interface name could not be determined");
}
- $netsh_command .= "netsh.exe firewall set portopening";
+ $netsh_command .= "$system32_path/netsh.exe firewall set portopening";
$netsh_command .= " name = \"Cygwin SSHD\"";
$netsh_command .= " protocol = TCP";
$netsh_command .= " port = 22";
@@ -4291,8 +4364,9 @@ sub firewall_enable_ssh_private {
return;
}
- my $management_node_keys = $self->data->get_management_node_keys();
- my $computer_node_name = $self->data->get_computer_node_name();
+ my $management_node_keys = $self->data->get_management_node_keys();
+ my $computer_node_name = $self->data->get_computer_node_name();
+ my $system32_path = $self->get_system32_path() || return;
my $netsh_command;
@@ -4302,7 +4376,7 @@ sub firewall_enable_ssh_private {
if ($public_interface_name) {
notify($ERRORS{'DEBUG'}, 0, "SSH will be disabled on public interface: $public_interface_name");
- $netsh_command .= "netsh.exe firewall delete portopening";
+ $netsh_command .= "$system32_path/netsh.exe firewall delete portopening";
$netsh_command .= " protocol = TCP";
$netsh_command .= " port = 22";
$netsh_command .= " interface = \"$public_interface_name\"";
@@ -4318,13 +4392,13 @@ sub firewall_enable_ssh_private {
if ($private_interface_name) {
notify($ERRORS{'DEBUG'}, 0, "SSH will be enabled on private interface: $private_interface_name");
- $netsh_command .= "netsh.exe firewall delete portopening";
+ $netsh_command .= "$system32_path/netsh.exe firewall delete portopening";
$netsh_command .= " protocol = TCP";
$netsh_command .= " port = 22";
$netsh_command .= " profile = ALL";
$netsh_command .= ' ;';
- $netsh_command .= "netsh.exe firewall set portopening";
+ $netsh_command .= "$system32_path/netsh.exe firewall set portopening";
$netsh_command .= " name = \"Cygwin SSHD\"";
$netsh_command .= " protocol = TCP";
$netsh_command .= " port = 22";
@@ -4334,7 +4408,7 @@ sub firewall_enable_ssh_private {
else {
notify($ERRORS{'WARNING'}, 0, "private interface name could not be determined, SSH will be enabled for all profiles");
- $netsh_command .= "netsh.exe firewall set portopening";
+ $netsh_command .= "$system32_path/netsh.exe firewall set portopening";
$netsh_command .= " name = \"Cygwin SSHD\"";
$netsh_command .= " protocol = TCP";
$netsh_command .= " port = 22";
@@ -4379,16 +4453,17 @@ sub firewall_enable_rdp {
# Check if the remote IP was passed correctly as an argument
my $remote_ip = shift;
- my $management_node_keys = $self->data->get_management_node_keys();
- my $computer_node_name = $self->data->get_computer_node_name();
-
+ my $management_node_keys = $self->data->get_management_node_keys();
+ my $computer_node_name = $self->data->get_computer_node_name();
+ my $system32_path = $self->get_system32_path() || return;
+
my $netsh_command;
# Set the key to allow remote connections whenever enabling RDP
# Include this in the SSH command along with the netsh.exe commands rather than calling it separately for faster execution
- $netsh_command .= 'reg.exe ADD "HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Terminal Server" /t REG_DWORD /v fDenyTSConnections /d 0 /f ; ';
+ $netsh_command .= $system32_path . '/reg.exe ADD "HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Terminal Server" /t REG_DWORD /v fDenyTSConnections /d 0 /f ; ';
- $netsh_command .= "netsh.exe firewall set portopening";
+ $netsh_command .= "$system32_path/netsh.exe firewall set portopening";
$netsh_command .= " name = \"Remote Desktop\"";
$netsh_command .= " protocol = TCP";
$netsh_command .= " port = 3389";
@@ -4438,14 +4513,15 @@ sub firewall_enable_rdp_private {
return;
}
- my $management_node_keys = $self->data->get_management_node_keys();
- my $computer_node_name = $self->data->get_computer_node_name();
+ my $management_node_keys = $self->data->get_management_node_keys();
+ my $computer_node_name = $self->data->get_computer_node_name();
+ my $system32_path = $self->get_system32_path() || return;
my $netsh_command;
# Set the key to allow remote connections whenever enabling RDP
# Include this in the SSH command along with the netsh.exe commands rather than calling it separately for faster execution
- $netsh_command .= 'reg.exe ADD "HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Terminal Server" /t REG_DWORD /v fDenyTSConnections /d 0 /f ; ';
+ $netsh_command .= $system32_path . '/reg.exe ADD "HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Terminal Server" /t REG_DWORD /v fDenyTSConnections /d 0 /f ; ';
# Get the public interface name
# Add command to disable RDP on public interface if its name is found
@@ -4453,7 +4529,7 @@ sub firewall_enable_rdp_private {
if ($public_interface_name) {
notify($ERRORS{'DEBUG'}, 0, "RDP will be disabled on public interface: $public_interface_name");
- $netsh_command .= "netsh.exe firewall delete portopening";
+ $netsh_command .= "$system32_path/netsh.exe firewall delete portopening";
$netsh_command .= " protocol = TCP";
$netsh_command .= " port = 3389";
$netsh_command .= " interface = \"$public_interface_name\"";
@@ -4475,7 +4551,7 @@ sub firewall_enable_rdp_private {
$netsh_command .= " profile = ALL";
$netsh_command .= ' ;';
- $netsh_command .= "netsh.exe firewall set portopening";
+ $netsh_command .= "$system32_path/netsh.exe firewall set portopening";
$netsh_command .= " name = \"Remote Desktop\"";
$netsh_command .= " protocol = TCP";
$netsh_command .= " port = 3389";
@@ -4485,7 +4561,7 @@ sub firewall_enable_rdp_private {
else {
notify($ERRORS{'WARNING'}, 0, "private interface name could not be determined, RDP will be enabled for all profiles");
- $netsh_command .= "netsh.exe firewall set portopening";
+ $netsh_command .= "$system32_path/netsh.exe firewall set portopening";
$netsh_command .= " name = \"Remote Desktop\"";
$netsh_command .= " protocol = TCP";
$netsh_command .= " port = 3389";
@@ -4527,8 +4603,9 @@ sub firewall_disable_rdp {
return;
}
- my $management_node_keys = $self->data->get_management_node_keys();
- my $computer_node_name = $self->data->get_computer_node_name();
+ my $management_node_keys = $self->data->get_management_node_keys();
+ my $computer_node_name = $self->data->get_computer_node_name();
+ my $system32_path = $self->get_system32_path() || return;
my $netsh_command;
@@ -4538,7 +4615,7 @@ sub firewall_disable_rdp {
if ($private_interface_name) {
notify($ERRORS{'DEBUG'}, 0, "RDP will be disabled on private interface: $private_interface_name");
- $netsh_command .= "netsh.exe firewall delete portopening";
+ $netsh_command .= "$system32_path/netsh.exe firewall delete portopening";
$netsh_command .= " protocol = TCP";
$netsh_command .= " port = 3389";
$netsh_command .= " interface = \"$private_interface_name\"";
@@ -4554,7 +4631,7 @@ sub firewall_disable_rdp {
if ($public_interface_name) {
notify($ERRORS{'DEBUG'}, 0, "RDP will be disabled on public interface: $public_interface_name");
- $netsh_command .= "netsh.exe firewall delete portopening";
+ $netsh_command .= "$system32_path/netsh.exe firewall delete portopening";
$netsh_command .= " protocol = TCP";
$netsh_command .= " port = 3389";
$netsh_command .= " interface = \"$public_interface_name\"";
@@ -4565,7 +4642,7 @@ sub firewall_disable_rdp {
}
# Add command to disable RDP for all profiles
- $netsh_command .= "netsh.exe firewall delete portopening";
+ $netsh_command .= "$system32_path/netsh.exe firewall delete portopening";
$netsh_command .= " protocol = TCP";
$netsh_command .= " port = 3389";
$netsh_command .= " profile = ALL";
@@ -4618,6 +4695,7 @@ sub get_network_configuration {
my $management_node_keys = $self->data->get_management_node_keys();
my $computer_node_name = $self->data->get_computer_node_name();
+ my $system32_path = $self->get_system32_path() || return;
# Check if a 'public' or 'private' network type argument was specified
my $network_type = lc(shift());
@@ -4635,7 +4713,7 @@ sub get_network_configuration {
my $ipconfig_attempt_limit = 2;
my ($ipconfig_exit_status, $ipconfig_output);
while (++$ipconfig_attempt) {
- ($ipconfig_exit_status, $ipconfig_output) = run_ssh_command($computer_node_name, $management_node_keys, $self->get_system32_path() . '/ipconfig.exe /all', '', '', 1);
+ ($ipconfig_exit_status, $ipconfig_output) = run_ssh_command($computer_node_name, $management_node_keys, $system32_path . '/ipconfig.exe /all', '', '', 1);
if (defined($ipconfig_exit_status) && $ipconfig_exit_status == 0) {
last;
}
@@ -5135,7 +5213,8 @@ sub enable_dhcp {
my $management_node_keys = $self->data->get_management_node_keys();
my $computer_node_name = $self->data->get_computer_node_name();
-
+ my $system32_path = $self->get_system32_path() || return;
+
my $interface_name_argument = shift;
my @interface_names;
if (!$interface_name_argument) {
@@ -5153,8 +5232,8 @@ sub enable_dhcp {
}
for my $interface_name (@interface_names) {
- # Use netsh to set the NIC to use DHCP
- my $set_dhcp_command = $self->get_system32_path() . '/netsh.exe interface ip set address name="' . $interface_name . '" source=dhcp';
+ # Use netsh.exe to set the NIC to use DHCP
+ my $set_dhcp_command = $system32_path . '/netsh.exe interface ip set address name="' . $interface_name . '" source=dhcp';
my ($set_dhcp_status, $set_dhcp_output) = run_ssh_command($computer_node_name, $management_node_keys, $set_dhcp_command);
if (defined($set_dhcp_status) && $set_dhcp_status == 0) {
notify($ERRORS{'OK'}, 0, "set interface '$interface_name' to use dhcp");
@@ -5196,11 +5275,12 @@ sub ipconfig_renew {
my $management_node_keys = $self->data->get_management_node_keys();
my $computer_node_name = $self->data->get_computer_node_name();
-
+ my $system32_path = $self->get_system32_path() || return;
+
my $interface_name_argument = shift;
# Assemble the ipconfig command, include the interface name if argument was specified
- my $ipconfig_command = $self->get_system32_path() . '/ipconfig.exe /renew';
+ my $ipconfig_command = $system32_path . '/ipconfig.exe /renew';
if ($interface_name_argument) {
$ipconfig_command .= " \"$interface_name_argument\"";
}
@@ -5241,9 +5321,10 @@ sub delete_capture_configuration_files {
my $management_node_keys = $self->data->get_management_node_keys();
my $computer_node_name = $self->data->get_computer_node_name();
-
+ my $system32_path = $self->get_system32_path() || return;
+
# Remove old logon and logoff scripts
- $self->delete_files_by_pattern($self->get_system32_path() . '/GroupPolicy/User/Scripts', '.*\(Prepare\|prepare\|Cleanup\|cleanup\|post_load\).*');
+ $self->delete_files_by_pattern($system32_path . '/GroupPolicy/User/Scripts', '.*\(Prepare\|prepare\|Cleanup\|cleanup\|post_load\).*');
# Remove old scripts and utilities
$self->delete_files_by_pattern('C:/Cygwin/home/root', '.*\(vbs\|exe\|cmd\|bat\|log\)');
@@ -5290,6 +5371,7 @@ sub add_group_policy_script {
my $management_node_keys = $self->data->get_management_node_keys();
my $computer_node_name = $self->data->get_computer_node_name();
+ my $system32_path = $self->get_system32_path() || return;
# Get the arguments
my $stage_argument = shift;
@@ -5321,7 +5403,7 @@ sub add_group_policy_script {
}
# Path to scripts.ini file
- my $scripts_ini = $self->get_system32_path() . '/GroupPolicy/User/Scripts/scripts.ini';
+ my $scripts_ini = $system32_path . '/GroupPolicy/User/Scripts/scripts.ini';
# Set the owner of scripts.ini to root
my $chown_command = "touch $scripts_ini && chown root $scripts_ini";
@@ -5539,6 +5621,7 @@ sub remove_group_policy_script {
my $management_node_keys = $self->data->get_management_node_keys();
my $computer_node_name = $self->data->get_computer_node_name();
+ my $system32_path = $self->get_system32_path() || return;
# Get the arguments
my $stage_argument = shift;
@@ -5566,7 +5649,7 @@ sub remove_group_policy_script {
}
# Path to scripts.ini file
- my $scripts_ini = $self->get_system32_path() . '/GroupPolicy/User/Scripts/scripts.ini';
+ my $scripts_ini = $system32_path . '/GroupPolicy/User/Scripts/scripts.ini';
# Set the owner of scripts.ini to root
my $chown_command = "touch $scripts_ini && chown root $scripts_ini";
@@ -5779,9 +5862,9 @@ sub run_gpupdate {
my $management_node_keys = $self->data->get_management_node_keys();
my $computer_node_name = $self->data->get_computer_node_name();
+ my $system32_path = $self->get_system32_path() || return;
- # Set the owner of scripts.ini to root
- my $gpupdate_command = 'cmd.exe /c ' . $self->get_system32_path() . '/gpupdate.exe /Force';
+ my $gpupdate_command = "$system32_path/cmd.exe /c $system32_path/gpupdate.exe /Force";
my ($gpupdate_status, $gpupdate_output) = run_ssh_command($computer_node_name, $management_node_keys, $gpupdate_command);
if (defined($gpupdate_output) && !grep(/error/i, @{$gpupdate_output})) {
notify($ERRORS{'OK'}, 0, "ran gpupdate /force");
@@ -6061,7 +6144,8 @@ sub clean_hard_drive {
my $management_node_keys = $self->data->get_management_node_keys();
my $computer_node_name = $self->data->get_computer_node_name();
-
+ my $system32_path = $self->get_system32_path() || return;
+
# Note: attempt to delete everything under C:\RECYCLER before running cleanmgr.exe
# The Recycle Bin occasionally becomes corrupted
# cleanmgr.exe will hang with an "OK/Cancel" box on the screen if this happens
@@ -6191,7 +6275,7 @@ EOF
}
# Run cleanmgr.exe
- my $command = $self->get_system32_path() . '/cleanmgr.exe /SAGERUN:01';
+ my $command = $system32_path . '/cleanmgr.exe /SAGERUN:01';
my ($status_cleanmgr, $output_cleanmgr) = run_ssh_command($computer_node_name, $management_node_keys, $command);
if (defined($status_cleanmgr) && $status_cleanmgr == 0) {
notify($ERRORS{'OK'}, 0, "ran cleanmgr.exe");
@@ -6227,14 +6311,15 @@ sub start_service {
my $management_node_keys = $self->data->get_management_node_keys();
my $computer_node_name = $self->data->get_computer_node_name();
-
+ my $system32_path = $self->get_system32_path() || return;
+
my $service_name = shift;
if (!$service_name) {
notify($ERRORS{'WARNING'}, 0, "service name was not passed as an argument");
return;
}
- my $command = $self->get_system32_path() . '/net.exe start "' . $service_name . '"';
+ my $command = $system32_path . '/net.exe start "' . $service_name . '"';
my ($status, $output) = run_ssh_command($computer_node_name, $management_node_keys, $command);
if (defined($status) && $status == 0) {
notify($ERRORS{'OK'}, 0, "started service: $service_name");
@@ -6273,14 +6358,15 @@ sub stop_service {
my $management_node_keys = $self->data->get_management_node_keys();
my $computer_node_name = $self->data->get_computer_node_name();
-
+ my $system32_path = $self->get_system32_path() || return;
+
my $service_name = shift;
if (!$service_name) {
notify($ERRORS{'WARNING'}, 0, "service name was not passed as an argument");
return;
}
- my $command = $self->get_system32_path() . '/net.exe stop "' . $service_name . '"';
+ my $command = $system32_path . '/net.exe stop "' . $service_name . '"';
my ($status, $output) = run_ssh_command($computer_node_name, $management_node_keys, $command);
if (defined($status) && $status == 0) {
notify($ERRORS{'OK'}, 0, "stopped service: $service_name");
@@ -6325,14 +6411,15 @@ sub service_exists {
my $management_node_keys = $self->data->get_management_node_keys();
my $computer_node_name = $self->data->get_computer_node_name();
-
+ my $system32_path = $self->get_system32_path() || return;
+
my $service_name = shift;
if (!$service_name) {
notify($ERRORS{'WARNING'}, 0, "service name was not passed as an argument");
return;
}
- my $command = $self->get_system32_path() . '/sc.exe query "' . $service_name . '"';
+ my $command = $system32_path . '/sc.exe query "' . $service_name . '"';
my ($status, $output) = run_ssh_command($computer_node_name, $management_node_keys, $command, '', '', 1);
if (defined($output) && grep(/service does not exist/i, @{$output})) {
notify($ERRORS{'DEBUG'}, 0, "service does not exist: $service_name");
@@ -6380,7 +6467,8 @@ sub get_installed_applications {
my $management_node_keys = $self->data->get_management_node_keys();
my $computer_node_name = $self->data->get_computer_node_name();
-
+ my $system32_path = $self->get_system32_path() || return;
+
# Get an optional regex filter string
my $regex_filter = shift;
if ($regex_filter) {
@@ -6391,7 +6479,7 @@ sub get_installed_applications {
}
# Attempt to query the registry for installed applications
- my $reg_query_command = $self->get_system32_path() . '/reg.exe QUERY "HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall" /s';
+ my $reg_query_command = $system32_path . '/reg.exe QUERY "HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall" /s';
my ($reg_query_exit_status, $reg_query_output) = run_ssh_command($computer_node_name, $management_node_keys, $reg_query_command, '', '', 1);
if (defined($reg_query_exit_status) && $reg_query_exit_status == 0) {
notify($ERRORS{'DEBUG'}, 0, "queried Uninstall registry keys");
@@ -6533,9 +6621,10 @@ sub get_task_list {
my $management_node_keys = $self->data->get_management_node_keys();
my $computer_node_name = $self->data->get_computer_node_name();
-
+ my $system32_path = $self->get_system32_path() || return;
+
# Attempt to run tasklist.exe with /NH for no header
- my $tasklist_command = $self->get_system32_path() . '/tasklist.exe /NH /V';
+ my $tasklist_command = $system32_path . '/tasklist.exe /NH /V';
my ($tasklist_exit_status, $tasklist_output) = run_ssh_command($computer_node_name, $management_node_keys, $tasklist_command, '', '', 1);
if (defined($tasklist_exit_status) && $tasklist_exit_status == 0) {
notify($ERRORS{'DEBUG'}, 0, "ran tasklist.exe");
@@ -6635,6 +6724,7 @@ sub apply_security_templates {
my $management_node_keys = $self->data->get_management_node_keys();
my $computer_node_name = $self->data->get_computer_node_name();
+ my $system32_path = $self->get_system32_path() || return;
# Get an array containing the configuration directory paths on the management node
# This is made up of all the the $SOURCE_CONFIGURATION_DIRECTORY values for the OS class and it's parent classes
@@ -6709,7 +6799,7 @@ sub apply_security_templates {
}
# Assemble the paths secedit needs
- my $secedit_exe = $self->get_system32_path() . '/secedit.exe';
+ my $secedit_exe = $system32_path . '/secedit.exe';
my $secedit_db = '$SYSTEMROOT/security/Database/' . "$inf_count\_$inf_file_root.sdb";
my $secedit_log = '$SYSTEMROOT/security/Logs/' . "$inf_count\_$inf_file_root.log";
@@ -6776,6 +6866,7 @@ sub kill_process {
my $management_node_keys = $self->data->get_management_node_keys();
my $computer_node_name = $self->data->get_computer_node_name();
+ my $system32_path = $self->get_system32_path() || return;
# Typical output:
# Task was killed, exit status = 0:
@@ -6788,7 +6879,7 @@ sub kill_process {
# ERROR: The search filter cannot be recognized.
# Attempt to kill task
- my $taskkill_command = $self->get_system32_path() . "/taskkill.exe /F /T /FI \"IMAGENAME eq $task_pattern\"";
+ my $taskkill_command = $system32_path . "/taskkill.exe /F /T /FI \"IMAGENAME eq $task_pattern\"";
my ($taskkill_exit_status, $taskkill_output) = run_ssh_command($computer_node_name, $management_node_keys, $taskkill_command, '', '', '1');
if (defined($taskkill_exit_status) && $taskkill_exit_status == 0 && (my @killed = grep(/SUCCESS/, @$taskkill_output))) {
notify($ERRORS{'OK'}, 0, scalar @killed . "processe(s) killed matching pattern: $task_pattern\n" . join("\n", @killed));
@@ -7128,6 +7219,7 @@ sub registry_query_value {
my $management_node_keys = $self->data->get_management_node_keys();
my $computer_node_name = $self->data->get_computer_node_name();
+ my $system32_path = $self->get_system32_path() || return;
# Get and check the arguments
my $key_name = shift;
@@ -7138,7 +7230,7 @@ sub registry_query_value {
}
# Assemble the query command string
- my $reg_query_command = $self->get_system32_path() . "/reg.exe QUERY \"$key_name\"";
+ my $reg_query_command = $system32_path . "/reg.exe QUERY \"$key_name\"";
# Check if the value name argument was specified
my $query_mode;
@@ -7225,7 +7317,11 @@ sub set_static_public_address {
notify($ERRORS{'CRITICAL'}, 0, "subroutine can only be called as a VCL::Module module object method");
return;
}
-
+
+ my $management_node_keys = $self->data->get_management_node_keys();
+ my $computer_node_name = $self->data->get_computer_node_name();
+ my $system32_path = $self->get_system32_path() || return;
+
# Make sure public IP configuration is static
my $ip_configuration = $self->data->get_management_node_public_ip_configuration() || 'undefined';
unless ($ip_configuration =~ /static/i) {
@@ -7252,15 +7348,12 @@ sub set_static_public_address {
return;
}
- my $management_node_keys = $self->data->get_management_node_keys();
- my $computer_node_name = $self->data->get_computer_node_name();
-
notify($ERRORS{'DEBUG'}, 0, "network configuration:\ninterface: $public_interface_name\npublic IP address: $public_ip_address\nsubnet mask=$subnet_mask\ndefault gateway=$default_gateway\ndns server=$dns_server");
# Set the static public IP address
- my $address_command = "netsh interface ip set address name=\"$public_interface_name\" source=static addr=$public_ip_address mask=$subnet_mask gateway=$default_gateway gwmetric=0";
+ my $address_command = "$system32_path/netsh.exe interface ip set address name=\"$public_interface_name\" source=static addr=$public_ip_address mask=$subnet_mask gateway=$default_gateway gwmetric=0";
- # Set number of attempts to try netsh commands
+ # Set number of attempts to try netsh.exe commands
my $max_attempts = 3;
my $address_attempts = 0;
while ($address_attempts < $max_attempts) {
@@ -7287,7 +7380,7 @@ sub set_static_public_address {
}
# Set the static DNS server address
- my $dns_command = "netsh interface ip set dns name=\"$public_interface_name\" source=static addr=$dns_server_primary register=none";
+ my $dns_command = "$system32_path/netsh.exe interface ip set dns name=\"$public_interface_name\" source=static addr=$dns_server_primary register=none";
my ($dns_exit_status, $dns_output) = run_ssh_command($computer_node_name, $management_node_keys, $dns_command);
if (defined($dns_exit_status) && $dns_exit_status == 0) {
notify($ERRORS{'DEBUG'}, 0, "set static DNS server address to $dns_server_primary");
@@ -7303,7 +7396,7 @@ sub set_static_public_address {
# We are only going to set up alternate dns server
if(defined($dns_server_alt1) && $dns_server_alt1){
- my $dns_alt1_command = "netsh interface ip add dns name=\"$public_interface_name\" addr=$dns_server_alt1";
+ my $dns_alt1_command = "$system32_path/netsh.exe interface ip add dns name=\"$public_interface_name\" addr=$dns_server_alt1";
my ($dns_a_exit_status, $dns_a_output) = run_ssh_command($computer_node_name, $management_node_keys, $dns_alt1_command);
if (defined($dns_a_exit_status) && $dns_a_exit_status == 0) {
notify($ERRORS{'DEBUG'}, 0, "set static DNS server address to $dns_server_alt1");
@@ -7503,7 +7596,7 @@ sub configure_time_synchronization {
my $management_node_keys = $self->data->get_management_node_keys();
my $computer_node_name = $self->data->get_computer_node_name();
- my $system32_path = $self->get_system32_path();
+ my $system32_path = $self->get_system32_path() || return;
my $time_source = "time.nist.gov time-a.nist.gov time-b.nist.gov time.windows.com";
@@ -7517,9 +7610,9 @@ sub configure_time_synchronization {
$time_command .= "$system32_path/w32tm.exe /register ; ";
# Start the service and configure it
- $time_command .= "net start w32time 2>/dev/null ; ";
+ $time_command .= "$system32_path/net.exe start w32time 2>/dev/null ; ";
$time_command .= "$system32_path/w32tm.exe /config /manualpeerlist:\"$time_source\" /syncfromflags:manual /update ; ";
- $time_command .= "net stop w32time && net start w32time ; ";
+ $time_command .= "$system32_path/net.exe stop w32time && $system32_path/net.exe start w32time ; ";
# Synchronize the time
$time_command .= "$system32_path/w32tm.exe /resync /nowait";
@@ -7632,21 +7725,27 @@ sub get_system32_path {
my $self = shift;
unless (ref($self) && $self->isa('VCL::Module')) {
notify($ERRORS{'CRITICAL'}, 0, "subroutine can only be called as a VCL::Module module object method");
- return;
+ return;
}
# Check if architecture has previously been determined
- # If not, check if OS is 32 or 64-bit
- if ($self->{SYSTEM32_PATH}) {
- #notify($ERRORS{'DEBUG'}, 0, "System32 string previously detected: $self->{SYSTEM32_PATH}");
+ return $self->{SYSTEM32_PATH} if $self->{SYSTEM32_PATH};
+
+ my $computer_name = $self->data->get_computer_short_name();
+
+ # Make sure SSH is responding
+ if (!$self->is_ssh_responding()) {
[... 77 lines stripped ...]