in managementnode/lib/VCL/Module/OS.pm [368:504]
sub add_user_accounts {
my $self = shift;
if (ref($self) !~ /VCL::Module/i) {
notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
return;
}
my $request_user_id = $self->data->get_user_id();
my $request_state_name = $self->data->get_request_state_name();
my $reservation_id = $self->data->get_reservation_id();
my $reservation_users = $self->data->get_reservation_users();
my $reservation_password = $self->data->get_reservation_password(0);
my $computer_node_name = $self->data->get_computer_node_name();
# Collect users in reservationaccounts table
my $reservation_accounts = get_reservation_accounts($reservation_id);
# Add users
RESERVATION_USER: foreach my $user_id (sort keys %$reservation_users) {
my $username = $reservation_users->{$user_id}{unityid};
my $uid = $reservation_users->{$user_id}{uid};
my $root_access = $reservation_users->{$user_id}{ROOTACCESS};
my $use_public_keys = $reservation_users->{$user_id}{usepublickeys};
# If the $use_public_keys flag is set, retrieve the keys
my $ssh_public_keys;
if ($use_public_keys) {
$ssh_public_keys = $reservation_users->{$user_id}{sshpublickeys};
}
my $password;
# Check if entry needs to be added to the useraccounts table
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 {
notify($ERRORS{'DEBUG'}, 0, "entry does not already exist in useraccounts table for $username (ID: $user_id)");
# Determine whether or not the user account's password should be set
my $should_set_user_password = 1;
if ($self->can('should_set_user_password')) {
$should_set_user_password = $self->should_set_user_password($user_id);
if (!defined($should_set_user_password)) {
notify($ERRORS{'CRITICAL'}, 0, "failed to determine if user account password should be set, user ID $user_id, assuming password should be set");
$should_set_user_password = 1;
}
}
if ($should_set_user_password) {
# Check if this is the request owner user ID and the reservation password has already been set
if ($user_id eq $request_user_id) {
if ($reservation_password) {
$password = $reservation_password;
notify($ERRORS{'DEBUG'}, 0, "user $username (ID: $user_id) is request owner, using existing reservation password: $password");
}
else {
# Generate a new random password
$password = getpw();
$self->data->set_reservation_password($password);
notify($ERRORS{'DEBUG'}, 0, "user $username (ID: $user_id) is request owner, generated new password: $password");
# Update the password in the reservation table
if (!update_reservation_password($reservation_id, $password)) {
$self->reservation_failed("failed to update password in the reservation table");
return;
}
}
}
else {
# Generate a new random password
$password = getpw();
notify($ERRORS{'DEBUG'}, 0, "user $username (ID: $user_id) is not the request owner, generated new password: $password");
}
}
# Add an entry to the useraccounts table
if (!add_reservation_account($reservation_id, $user_id, $password)) {
notify($ERRORS{'CRITICAL'}, 0, "failed to add entry to reservationaccounts table for $username (ID: $user_id)");
return;
}
# Create user on the OS
if (!$self->create_user({
username => $username,
password => $password,
root_access => $root_access,
uid => $uid,
ssh_public_keys => $ssh_public_keys,
})) {
notify($ERRORS{'WARNING'}, 0, "failed to create user on $computer_node_name, removing entry added to reservationaccounts table");
# 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)");
}
return;
}
}
}
# Remove anyone listed in reservationaccounts that is not a reservation user
foreach my $user_id (sort keys %$reservation_accounts) {
if (defined($reservation_users->{$user_id})) {
next;
}
my $username = $reservation_accounts->{$user_id}{username};
notify($ERRORS{'OK'}, 0, "user $username (ID: $user_id) exists in reservationsaccounts table but is not assigned to this reservation, attempting to delete user");
# Delete the user from OS
if (!$self->delete_user($username)) {
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{'CRITICAL'}, 0, "failed to delete entry from reservationaccounts table for user $username (ID: $user_id)");
}
}
return 1;
}