in managementnode/lib/VCL/Module/OS/Linux.pm [3058:3226]
sub delete_user {
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 0;
}
# Make sure the user login ID was passed
my $username = shift;
$username = $self->data->get_user_login_id() if (!$username);
if (!$username) {
notify($ERRORS{'WARNING'}, 0, "user could not be determined");
return;
}
my $computer_node_name = $self->data->get_computer_node_name();
# 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;
}
# Check if the user is logged in
if ($self->user_logged_in($username)) {
if (!$self->logoff_user($username)) {
notify($ERRORS{'WARNING'}, 0, "failed to delete user $username from $computer_node_name, user appears to be logged in but could NOT be logged off");
return;
}
}
# Determine if home directory is on a local device or network share
my $home_directory_path = "/home/$username";
my $home_directory_on_local_disk = $self->is_file_on_local_disk($home_directory_path);
# Assemble the userdel command
my $userdel_command = "/usr/sbin/userdel";
my $delete_home_directory = 0;
if ($home_directory_on_local_disk) {
$delete_home_directory = 1;
# Fetch exclude_list
my @exclude_list = $self->get_exclude_list();
if ((grep(/\/home\/$username/, @exclude_list))) {
notify($ERRORS{'DEBUG'}, 0, "home directory will NOT be deleted: $home_directory_path");
$delete_home_directory = 0;
}
else {
# Make sure no NFS shares are mounted under home directory
my @nfs_mount_strings = $self->get_nfs_mount_strings();
for my $nfs_mount_string (@nfs_mount_strings) {
my ($nfs_remote_host, $nfs_remote_path, $nfs_local_path) = $nfs_mount_string =~
/
^
([^:]+) # Remote hostname or IP address
:
(\/.+) # Remote path
\s+
(\/.+) # Local path
\s+
nfs\d* # ' nfs ' or ' nfs4 '
\s+
/gx;
if ($nfs_local_path) {
if ($nfs_local_path =~ /^$home_directory_path/) {
notify($ERRORS{'WARNING'}, 0, "home directory will NOT be deleted, NFS share is mounted under it\n" .
"NFS mount string : $nfs_mount_string\n" .
"home directory path : $home_directory_path\n" .
"local mount path : $nfs_local_path"
);
$delete_home_directory = 0;
last;
}
else {
notify($ERRORS{'DEBUG'}, 0, "NFS share is NOT mounted under home directory\n" .
"NFS mount string : $nfs_mount_string\n" .
"home directory path : $home_directory_path\n" .
"local mount path : $nfs_local_path"
);
}
}
else {
notify($ERRORS{'WARNING'}, 0, "home directory will NOT be deleted: $home_directory_path, failed to parse NFS mount string: $nfs_mount_string");
$delete_home_directory = 0;
last;
}
}
}
}
if ($delete_home_directory) {
notify($ERRORS{'DEBUG'}, 0, "home directory will be deleted: $home_directory_path");
$userdel_command .= ' -r';
}
$userdel_command .= " $username";
# Call userdel to delete the user
my ($userdel_exit_status, $userdel_output) = $self->execute($userdel_command);
if (!defined($userdel_output)) {
notify($ERRORS{'WARNING'}, 0, "failed to execute command to delete user from $computer_node_name: $username");
return;
}
elsif (grep(/does not exist/i, @$userdel_output)) {
notify($ERRORS{'DEBUG'}, 0, "user '$username' NOT deleted from $computer_node_name because it does not exist");
}
elsif (grep(/not found/i, @$userdel_output)) {
notify($ERRORS{'DEBUG'}, 0, "userdel warning '$username' $computer_node_name :\n" . join("\n", @$userdel_output));
}
elsif (grep(/userdel: /i, @$userdel_output)) {
notify($ERRORS{'WARNING'}, 0, "failed to delete user '$username' from $computer_node_name, command: '$userdel_command', exit status: $userdel_exit_status, output:\n" . join("\n", @$userdel_output));
return;
}
else {
notify($ERRORS{'OK'}, 0, "deleted user '$username' from $computer_node_name");
}
# Call groupdel to delete the user's group
my $groupdel_command = "/usr/sbin/groupdel $username";
my ($groupdel_exit_status, $groupdel_output) = $self->execute($groupdel_command);
if (!defined($groupdel_output)) {
notify($ERRORS{'WARNING'}, 0, "failed to execute command to delete group from $computer_node_name: $username");
return;
}
elsif (grep(/does not exist/i, @$groupdel_output)) {
notify($ERRORS{'DEBUG'}, 0, "group '$username' NOT deleted from $computer_node_name because it does not exist");
}
elsif (grep(/groupdel: /i, @$groupdel_output)) {
notify($ERRORS{'WARNING'}, 0, "failed to delete group '$username' from $computer_node_name, command: '$groupdel_command', output:\n" . join("\n", @$groupdel_output));
}
else {
notify($ERRORS{'OK'}, 0, "deleted group '$username' from $computer_node_name");
}
# Remove username from AllowUsers lines in ssh/external_sshd_config
my $external_sshd_config_file_path = '/etc/ssh/external_sshd_config';
my @original_lines = $self->get_file_contents($external_sshd_config_file_path);
my @modified_lines;
my $new_file_contents;
for my $line (@original_lines) {
if ($line =~ /AllowUsers.*\s$username(\s|$)/) {
push @modified_lines, $line;
$line =~ s/\s*$username//g;
# If user was only username listed on line, don't add empty AllowUsers line back to file
if ($line !~ /AllowUsers\s+\w/) {
next;
}
}
$new_file_contents .= "$line\n";
}
if (@modified_lines) {
notify($ERRORS{'OK'}, 0, "removing or modifying AllowUsers lines in $external_sshd_config_file_path:\n" . join("\n", @modified_lines));
$self->create_text_file($external_sshd_config_file_path, $new_file_contents) || return;
}
else {
notify($ERRORS{'DEBUG'}, 0, "no AllowUsers lines were found in $external_sshd_config_file_path containing '$username'");
}
# Remove lines from sudoers
$self->revoke_administrative_access($username);
return 1;
} ## end sub delete_user