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__