Author: arkurth
Date: Fri Jul  7 17:48:04 2017
New Revision: 1801199

URL: http://svn.apache.org/viewvc?rev=1801199&view=rev
Log:
VCL-1058
Updated OS.pm::add_user_accounts. If state = 'servermodified' and the account 
already exists, it now calls either grant_administrative_access or 
revoke_administrative_access.

Updated Linux.pm::create_user
Cleaned up OS.pm::delete_user_accounts. It had 2 nearly identical loops with 
duplicated code.

Updated pre_capture in Linux.pm and Windows.pm to call delete_user_accounts 
instead of delete_user.

Modified:
    vcl/trunk/managementnode/lib/VCL/Module/OS.pm
    vcl/trunk/managementnode/lib/VCL/Module/OS/Linux.pm
    vcl/trunk/managementnode/lib/VCL/Module/OS/Windows.pm

Modified: vcl/trunk/managementnode/lib/VCL/Module/OS.pm
URL: 
http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/Module/OS.pm?rev=1801199&r1=1801198&r2=1801199&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/Module/OS.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/Module/OS.pm Fri Jul  7 17:48:04 2017
@@ -400,6 +400,15 @@ sub add_user_accounts {
                if (defined($reservation_accounts->{$user_id}) && 
($request_state_name =~ /servermodified/)) {
                        # Entry already exists in useraccounts table and is 
servermodified, assume everything is correct skip to next user
                        notify($ERRORS{'DEBUG'}, 0, "entry already exists in 
useraccounts table for $username (ID: $user_id) and request_state_name = 
$request_state_name");
+                       
+                       # Make sure user's root access is correct - may have 
been moved from admin to access group, and vice versa
+                       if ($root_access) {
+                               $self->grant_administrative_access($username) 
if ($self->can('grant_administrative_access'));
+                       }
+                       else {
+                               $self->revoke_administrative_access($username) 
if ($self->can('revoke_administrative_access'));
+                       }
+                       
                        next RESERVATION_USER;
                }
                else {
@@ -512,54 +521,39 @@ sub delete_user_accounts {
        
        my $reservation_id = $self->data->get_reservation_id();
        my $computer_node_name = $self->data->get_computer_node_name();
+       
+       my %username_hash;
+       
        my $reservation_users = $self->data->get_reservation_users();
+       foreach my $user_id (sort keys %$reservation_users) {
+               my $username = $reservation_users->{$user_id}{unityid};
+               $username_hash{$username} = $user_id;
+       }
 
        # Collect users in reservationaccounts table
        my $reservation_accounts = get_reservation_accounts($reservation_id);
+       foreach my $user_id (sort keys %$reservation_accounts) {
+               my $username = $reservation_accounts->{$user_id}{username};
+               $username_hash{$username} = $user_id;
+       }
        
-       my $errors = 0;
+       my $error_encountered = 0;
        
        # Delete users
-       foreach my $user_id (sort keys %$reservation_users) {
-               my $username = $reservation_users->{$user_id}{unityid};
-               
-               # Delete the key from reservation accounts, these will be 
processed next
-               delete $reservation_accounts->{$user_id};
+       foreach my $username (sort keys %username_hash) {
+               my $user_id = $username_hash{$username};
                
                # Delete user on the OS
                if (!$self->delete_user($username)) {
-                       $errors = 1;
+                       $error_encountered = 1;
                        notify($ERRORS{'WARNING'}, 0, "failed to delete user on 
$computer_node_name");
-                       
-                       # Delete entry to the useraccounts table
-                       if (!delete_reservation_account($reservation_id, 
$user_id)) {
-                               notify($ERRORS{'CRITICAL'}, 0, "failed to 
delete entry from reservationaccounts table for $username (ID: $user_id)");
-                       }
-               }
-       }
-       
-       foreach my $user_id (sort keys %$reservation_accounts) {
-               my $username = $reservation_accounts->{$user_id}{username};
-               
-               # Delete the user from OS
-               if (!$self->delete_user($username)) {
-                       $errors = 1;
-                       notify($ERRORS{'WARNING'}, 0, "failed to delete user 
$username (ID: $user_id) from $computer_node_name");
-                       next;
                }
                
-               # Delete entry from reservationaccounts
-               if (!delete_reservation_account($reservation_id, $user_id)) {
-                       notify($ERRORS{'WARNING'}, 0, "failed to delete entry 
from reservationaccounts table for user $username (ID: $user_id)");
-               }
+               # Delete entry to the useraccounts table
+               delete_reservation_account($reservation_id, $user_id);
        }
        
-       if ($errors) {
-               return 0;
-       }
-       else {
-               return 1;
-       }
+       return !$error_encountered;
 }
 
 #//////////////////////////////////////////////////////////////////////////////
@@ -3104,9 +3098,11 @@ sub get_file_contents {
 =head2 remove_lines_from_file
 
  Parameters  : $file_path, $pattern
- Returns     : boolean
+ Returns     : integer or undefined
  Description : Removes all lines containing the pattern from the file. The
-               pattern must be a regular expression.
+               pattern must be a regular expression. Returns the number of 
lines
+               removed from the file which may be 0. Returns undefined if an
+               error occurred.
 
 =cut
 
@@ -3130,7 +3126,7 @@ sub remove_lines_from_file {
        
        if (!$self->file_exists($file_path)) {
                notify($ERRORS{'DEBUG'}, 0, "lines containing '$pattern' not 
removed because file does NOT exist: $file_path");
-               return 1;
+               return 0;
        }
        
        my @lines = $self->get_file_contents($file_path);
@@ -3152,7 +3148,7 @@ sub remove_lines_from_file {
        else {
                notify($ERRORS{'DEBUG'}, 0, "$file_path does NOT contain any 
lines matching pattern: '$pattern'");
        }
-       return 1;
+       return scalar(@lines_removed);
 }
 
 #//////////////////////////////////////////////////////////////////////////////

Modified: vcl/trunk/managementnode/lib/VCL/Module/OS/Linux.pm
URL: 
http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/Module/OS/Linux.pm?rev=1801199&r1=1801198&r2=1801199&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/Module/OS/Linux.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/Module/OS/Linux.pm Fri Jul  7 17:48:04 2017
@@ -400,9 +400,9 @@ sub pre_capture {
                notify($ERRORS{'WARNING'}, 0, "unable to log user off 
$computer_node_name");
        }
        
-       # Remove user and clean external ssh file
-       if ($self->delete_user()) {
-               notify($ERRORS{'OK'}, 0, "deleted user from 
$computer_node_name");
+       # Remove user accounts
+       if ($self->delete_user_accounts()) {
+               notify($ERRORS{'OK'}, 0, "deleted user accounts added by VCL 
from $computer_node_name");
        }
        
        # Attempt to set the root password to a known value
@@ -2998,18 +2998,23 @@ sub create_user {
        }
        
        # Add user to sudoers if necessary
-       if ($root_access && !$self->grant_root_access($username)) {
-               notify($ERRORS{'WARNING'}, 0, "failed to process 
grant_root_access for $username");
-               return;
+       if ($root_access) {
+               if (!$self->grant_administrative_access($username)) {
+                       notify($ERRORS{'WARNING'}, 0, "failed to process 
grant_administrative_access for $username");
+                       return;
+               }
+       }
+       else {
+               # Make sure user does not have root access
+               $self->revoke_administrative_access($username);
        }
        
        return 1;
 } ## end sub create_user
 
-
 #//////////////////////////////////////////////////////////////////////////////
 
-=head2 grant_root_access
+=head2 grant_administrative_access
 
  Parameters  : $username
  Returns     : boolean
@@ -3017,7 +3022,7 @@ sub create_user {
 
 =cut
 
-sub grant_root_access {
+sub grant_administrative_access {
        my $self = shift;
        if (ref($self) !~ /linux/i) {
                notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a 
function, it must be called as a class method");
@@ -3030,8 +3035,23 @@ sub grant_root_access {
                return;
        }
        
+       my $timestamp = makedatestring();
+       
        my $sudoers_file_path = '/etc/sudoers';
-       my $sudoers_line = "$username ALL= NOPASSWD: ALL";
+       
+       my @existing_lines = $self->get_file_contents($sudoers_file_path);
+       my @matching_lines;
+       for my $line (@existing_lines) {
+               if ($line =~ /^\s*$username\s/) {
+                       push @matching_lines, $line;
+               }
+       }
+       if (@matching_lines) {
+               notify($ERRORS{'DEBUG'}, 0, "$username was previously added to 
$sudoers_file_path:\n" . join("\n", @matching_lines));
+               return 1;
+       }
+       
+       my $sudoers_line = "$username ALL= NOPASSWD: ALL\t# Added by VCL, 
($timestamp)";
        if ($self->append_text_file($sudoers_file_path, $sudoers_line)) {
                notify($ERRORS{'DEBUG'}, 0, "appended line to 
$sudoers_file_path: '$sudoers_line'");
                return 1;
@@ -3044,6 +3064,40 @@ sub grant_root_access {
 
 #//////////////////////////////////////////////////////////////////////////////
 
+=head2 revoke_administrative_access
+
+ Parameters  : $username
+ Returns     : boolean
+ Description : Removes all entries from the sudoers file for the user.
+
+=cut
+
+sub revoke_administrative_access {
+       my $self = shift;
+       if (ref($self) !~ /linux/i) {
+               notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a 
function, it must be called as a class method");
+               return;
+       }
+       
+       my $username = shift;
+       if (!defined($username)) {
+               notify($ERRORS{'WARNING'}, 0, "username argument was not 
supplied");
+               return;
+       }
+       
+       my $sudoers_file_path = '/etc/sudoers';
+
+       # Remove lines from sudoers
+       if (defined($self->remove_lines_from_file($sudoers_file_path, 
"^[\\s#]*$username\\s"))) {
+               return 1;
+       }
+       else {
+               return;
+       }
+}
+
+#//////////////////////////////////////////////////////////////////////////////
+
 =head2 delete_user
 
  Parameters  : $username
@@ -3072,6 +3126,10 @@ sub delete_user {
        # Make sure the user exists
        if (!$self->user_exists($username)) {
                notify($ERRORS{'DEBUG'}, 0, "user NOT deleted from 
$computer_node_name because it does not exist: $username");
+               
+               # Make sure user does not exist in sudoers
+               $self->revoke_administrative_access($username);
+               
                return 1;
        }
        
@@ -3164,7 +3222,7 @@ sub delete_user {
        }
        
        # Remove lines from sudoers
-       $self->remove_lines_from_file('/etc/sudoers', "^\\s*$username\\s+") || 
return;
+       $self->revoke_administrative_access($username);
        
        return 1;
 } ## end sub delete_user

Modified: vcl/trunk/managementnode/lib/VCL/Module/OS/Windows.pm
URL: 
http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows.pm?rev=1801199&r1=1801198&r2=1801199&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/Module/OS/Windows.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/Module/OS/Windows.pm Fri Jul  7 17:48:04 
2017
@@ -411,9 +411,9 @@ sub pre_capture {
 
 =cut
 
-       my $deleted_user = $self->delete_user();
-       if (!$deleted_user) {
-               notify($ERRORS{'DEBUG'}, 0, "unable to delete user, will try 
again after reboot");
+       my $deleted_user_accounts = $self->delete_user_accounts();
+       if (!$deleted_user_accounts) {
+               notify($ERRORS{'DEBUG'}, 0, "unable to delete user accounts, 
will try again after reboot");
        }
 
 =item *
@@ -616,8 +616,8 @@ sub pre_capture {
 
 =cut
 
-       if (!$deleted_user && !$self->delete_user()) {
-               notify($ERRORS{'WARNING'}, 0, "unable to delete user after 
reboot");
+       if (!$deleted_user_accounts && !$self->delete_user_accounts()) {
+               notify($ERRORS{'WARNING'}, 0, "unable to delete user accounts 
after reboot");
                return 0;
        }
 
@@ -14657,6 +14657,58 @@ sub ad_user_exists {
 }
 
 #//////////////////////////////////////////////////////////////////////////////
+
+=head2 grant_administrative_access
+
+ Parameters  : $username
+ Returns     : boolean
+ Description : Adds the user to the local Administrators group.
+
+=cut
+
+sub grant_administrative_access {
+       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 $username = shift;
+       if (!defined($username)) {
+               notify($ERRORS{'WARNING'}, 0, "username argument was not 
supplied");
+               return;
+       }
+       
+       return $self->add_user_to_group($username, "Administrators");
+}
+
+#//////////////////////////////////////////////////////////////////////////////
+
+=head2 revoke_administrative_access
+
+ Parameters  : $username
+ Returns     : boolean
+ Description : Removes the user to the local Administrators group.
+
+=cut
+
+sub revoke_administrative_access {
+       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 $username = shift;
+       if (!defined($username)) {
+               notify($ERRORS{'WARNING'}, 0, "username argument was not 
supplied");
+               return;
+       }
+       
+       return $self->remove_user_from_group($username, 'Administrators');
+}
+
+#//////////////////////////////////////////////////////////////////////////////
 
 1;
 __END__


Reply via email to