# Functions for managing a domain's Unix user
$feature_depends{'unix'} = [ 'dir' ];
# setup_unix(&domain)
# Creates the Unix user and group for a domain
sub setup_unix
{
local $tmpl = &get_template($_[0]->{'template'});
&require_useradmin();
local (%uinfo, %ginfo);
# Check if the UID or GID has been allocated to someone else, and if so
# re-allocate them. Also allocate if they haven't been done yet.
local @allusers = &list_all_users();
local ($clash) = grep { $_->{'uid'} == $_[0]->{'uid'} } @allusers;
if ($clash || !$_[0]->{'uid'}) {
local (%taken, %utaken);
&build_taken(\%taken, \%utaken, \@allusers);
$_[0]->{'uid'} = &allocate_uid(\%taken);
}
local @allgroups = &list_all_groups();
local ($gclash) = grep { $_->{'gid'} == $_[0]->{'gid'} } @allgroups;
if ($gclash || !$_[0]->{'gid'}) {
local (%gtaken, %ggtaken);
&build_group_taken(\%gtaken, \%ggtaken, \@allgroups);
$_[0]->{'gid'} = &allocate_gid(\%gtaken);
}
if (&mail_system_needs_group() || $_[0]->{'gid'} == $_[0]->{'ugid'}) {
# Create the group
&$first_print(&text('setup_group', $_[0]->{'group'}));
&foreign_call($usermodule, "lock_user_files");
%ginfo = ( 'group', $_[0]->{'group'},
'gid', $_[0]->{'gid'},
);
eval {
local $main::error_must_die = 1;
&foreign_call($usermodule, "set_group_envs", \%ginfo,
'CREATE_GROUP');
&foreign_call($usermodule, "making_changes");
&foreign_call($usermodule, "create_group", \%ginfo);
&foreign_call($usermodule, "made_changes");
};
if (@$ || !defined(getgrnam($_[0]->{'group'}))) {
&delete_partial_group(\%ginfo);
&$second_print($@ ? &text('setup_ecrgroup2', $@)
: $text{'setup_ecrgroup'});
return 0;
}
&$second_print($text{'setup_done'});
}
else {
# Server has no group!
delete($_[0]->{'gid'});
delete($_[0]->{'group'});
}
# Then the user
&$first_print(&text('setup_user', $_[0]->{'user'}));
%uinfo = ( 'user', $_[0]->{'user'},
'uid', $_[0]->{'uid'},
'gid', $_[0]->{'ugid'},
'pass', $_[0]->{'enc_pass'} ||
&foreign_call($usermodule, "encrypt_password",
$_[0]->{'pass'}),
'real', $_[0]->{'owner'},
'home', $_[0]->{'home'},
'shell', &default_available_shell('owner'),
'mailbox', $_[0]->{'user'},
'dom', $_[0]->{'dom'},
'dom_prefix', substr($_[0]->{'dom'}, 0, 1),
'plainpass', $_[0]->{'pass'},
'domainowner', 1,
'unix', 1,
'email', $_[0]->{'user'}.'\@'.$_[0]->{'dom'},
);
&set_pass_change(\%uinfo);
eval {
local $main::error_must_die = 1;
&foreign_call($usermodule, "set_user_envs", \%uinfo,
'CREATE_USER', $_[0]->{'pass'}, [ ]);
&foreign_call($usermodule, "making_changes");
&foreign_call($usermodule, "create_user", \%uinfo);
&foreign_call($usermodule, "made_changes");
&foreign_call($usermodule, "unlock_user_files");
if ($config{'other_doms'}) {
&foreign_call($usermodule, "other_modules",
"useradmin_create_user", \%uinfo);
}
};
if ($@ || !defined(getpwnam($_[0]->{'user'}))) {
&delete_partial_group(\%ginfo) if (%ginfo);
&delete_partial_user(\%uinfo);
&$second_print($@ ? &text('setup_ecruser2', $@)
: $text{'setup_ecruser'});
return 0;
}
&$second_print($text{'setup_done'});
# Set the user's quota
&$first_print($text{'setup_usermail'});
if (&has_home_quotas()) {
&set_server_quotas($_[0]);
}
eval {
# Create mail file
local $main::error_must_die = 1;
&create_mail_file(\%uinfo);
# Create virtuser pointing to new user, and possibly generics entry
if ($_[0]->{'mail'}) {
local @virts = &list_virtusers();
local $email = $_[0]->{'user'}."\@".$_[0]->{'dom'};
local ($virt) = grep { $_->{'from'} eq $email } @virts;
if (!$virt) {
$virt = { 'from' => $email,
'to' => [ $_[0]->{'user'} ] };
&create_virtuser($virt);
&sync_alias_virtuals($_[0]);
}
if ($config{'generics'}) {
&create_generic($_[0]->{'user'}, $email);
}
}
};
if ($@) {
&$second_print(&text('setup_eusermail', $@));
}
else {
&$second_print($text{'setup_done'});
}
# Add to denied SSH group and domain owner group. Don't let the failure of
# this block the whole user creation though
&$first_print($text{'setup_usergroups'});
eval {
local $main::error_must_die = 1;
&build_denied_ssh_group($_[0]);
&update_domain_owners_group($_[0]);
};
if ($@) {
&$second_print(&text('setup_eusergroups', $@));
}
else {
&$second_print($text{'setup_done'});
}
# Set the user's Usermin IMAP password
&set_usermin_imap_password(\%uinfo);
return 1;
}
# modify_unix(&domain, &olddomain)
# Change the password and real name for a domain unix user
sub modify_unix
{
if (!$_[0]->{'parent'}) {
# Check for a user change
&require_useradmin();
local @allusers = &list_domain_users($_[1]);
local ($uinfo) = grep { $_->{'user'} eq $_[1]->{'user'} } @allusers;
if ($uinfo && ($_[0]->{'pass_set'} ||
$_[0]->{'user'} ne $_[1]->{'user'} ||
$_[0]->{'home'} ne $_[1]->{'home'} ||
$_[0]->{'owner'} ne $_[1]->{'owner'})) {
&foreign_call($usermodule, "lock_user_files");
local %old = %$uinfo;
&$first_print($text{'save_user'});
$uinfo->{'real'} = $_[0]->{'owner'};
if ($_[0]->{'pass_set'}) {
# Update the Unix user's password
local $enc = &foreign_call($usermodule,
"encrypt_password", $_[0]->{'pass'});
if ($d->{'disabled'}) {
# Just keep for later use when enabling
$d->{'disabled_oldpass'} = $enc;
}
else {
# Set password now
$uinfo->{'pass'} = $enc;
}
delete($d->{'enc_pass'}); # Any stored encrypted
# password is not valid
$uinfo->{'plainpass'} = $_[0]->{'pass'};
&set_pass_change($uinfo);
&set_usermin_imap_password($uinfo);
}
if ($_[0]->{'user'} ne $_[1]->{'user'}) {
# Unix user was re-named
$uinfo->{'olduser'} = $_[1]->{'user'};
$uinfo->{'user'} = $_[0]->{'user'};
&rename_mail_file($uinfo, \%old);
&rename_unix_cron_jobs($_[0]->{'user'},
$_[1]->{'user'});
}
if ($_[0]->{'home'} ne $_[1]->{'home'}) {
# Home directory was changed
$uinfo->{'home'} = $_[0]->{'home'};
}
if ($_[0]->{'owner'} ne $_[1]->{'owner'}) {
# Domain description was changed
$uinfo->{'real'} = $_[0]->{'owner'};
}
&modify_user($uinfo, \%old, undef);
if ($config{'other_doms'}) {
&foreign_call($usermodule, "other_modules",
"useradmin_modify_user", $uinfo, \%old);
}
&$second_print($text{'setup_done'});
&foreign_call($usermodule, "unlock_user_files");
}
if (&has_home_quotas() && $access{'edit'} == 1) {
# Update the unix user's and domain's quotas (if changed)
if ($_[0]->{'quota'} != $_[1]->{'quota'} ||
$_[0]->{'uquota'} != $_[1]->{'uquota'}) {
&$first_print($text{'save_quota'});
&set_server_quotas($_[0]);
&$second_print($text{'setup_done'});
}
}
# Check for a group change
local ($ginfo) = grep { $_->{'group'} eq $_[1]->{'group'} }
&list_all_groups();
if ($ginfo && $_[0]->{'group'} ne $_[1]->{'group'}) {
&foreign_call($usermodule, "lock_user_files");
local %old = %$ginfo;
&$first_print($text{'save_group'});
$ginfo->{'group'} = $_[0]->{'group'};
&foreign_call($usermodule, "set_group_envs", $ginfo,
'MODIFY_GROUP', \%old);
&foreign_call($usermodule, "making_changes");
&foreign_call($usermodule, "modify_group", \%old, $ginfo);
&foreign_call($usermodule, "made_changes");
&foreign_call($usermodule, "unlock_user_files");
&$second_print($text{'setup_done'});
}
}
elsif ($_[0]->{'parent'} && !$_[1]->{'parent'}) {
# Unix feature has been turned off .. so delete the user and group
&delete_unix($_[1]);
}
}
# delete_unix(&domain)
# Delete the unix user and group for a domain
sub delete_unix
{
&require_useradmin();
local @allusers = &foreign_call($usermodule, "list_users");
local ($uinfo) = grep { $_->{'user'} eq $_[0]->{'user'} } @allusers;
if (!$_[0]->{'parent'}) {
# Zero his quotas
if ($uinfo) {
&set_user_quotas($uinfo->{'user'}, 0, 0, $_[0]);
}
# Delete his cron jobs
&delete_unix_cron_jobs($_[0]->{'user'});
# Delete virtuser and generic
local @virts = &list_virtusers();
local $email = $_[0]->{'user'}."\@".$_[0]->{'dom'};
local ($virt) = grep { $_->{'from'} eq $email } @virts;
if ($virt) {
&delete_virtuser($virt);
&sync_alias_virtuals($_[0]);
}
if ($config{'generics'}) {
local %generics = &get_generics_hash();
local $g = $generics{$_[0]->{'user'}};
if ($g) {
&delete_generic($g);
}
}
# Delete his mail file
if ($uinfo && !$uinfo->{'nomailfile'}) {
&delete_mail_file($uinfo);
}
# Delete unix user
&foreign_call($usermodule, "lock_user_files");
if ($uinfo) {
&$first_print($text{'delete_user'});
&delete_user($uinfo, $_[0]);
if ($config{'other_doms'}) {
&foreign_call($usermodule, "other_modules",
"useradmin_delete_user", $uinfo);
}
&$second_print($text{'setup_done'});
}
# Delete unix group
local @allgroups = &foreign_call($usermodule, "list_groups");
local ($ginfo) = grep { $_->{'group'} eq $_[0]->{'group'} } @allgroups;
if ($ginfo) {
&$first_print($text{'delete_group'});
&foreign_call($usermodule, "set_group_envs", $ginfo, 'DELETE_GROUP');
&foreign_call($usermodule, "making_changes");
&foreign_call($usermodule, "delete_group", $ginfo);
&foreign_call($usermodule, "made_changes");
&$second_print($text{'setup_done'});
}
&foreign_call($usermodule, "unlock_user_files");
}
# Update any groups
&build_denied_ssh_group(undef, $_[0]);
&update_domain_owners_group(undef, $_[0]);
}
# validate_unix(&domain)
# Check for the Unix user and group
sub validate_unix
{
local ($d) = @_;
return undef if ($d->{'parent'}); # sub-servers have no user
local @users = &list_all_users();
local ($user) = grep { $_->{'user'} eq $d->{'user'} } @users;
return &text('validate_euser', $d->{'user'}) if (!$user);
if (&mail_system_needs_group() || $d->{'gid'} == $d->{'ugid'}) {
local @groups = &list_all_groups();
local ($group) = grep { $_->{'group'} eq $d->{'group'} } @groups;
return &text('validate_egroup', $d->{'group'}) if (!$group);
}
return undef;
}
# check_unix_clash(&domain, [field])
sub check_unix_clash
{
return 0 if ($_[0]->{'parent'}); # user already exists!
if (!$_[1] || $_[1] eq 'user') {
return 1 if (defined(getpwnam($_[0]->{'user'})));
}
if (!$_[1] || $_[1] eq 'group') {
return 1 if ($_[0]->{'group'} &&
defined(getgrnam($_[0]->{'group'})));
}
return 0;
}
# disable_unix(&domain)
# Lock out the password of this domain's Unix user
sub disable_unix
{
if (!$_[0]->{'parent'}) {
&require_useradmin();
&foreign_call($usermodule, "lock_user_files");
local @allusers = &foreign_call($usermodule, "list_users");
local ($uinfo) = grep { $_->{'user'} eq $_[0]->{'user'} } @allusers;
if ($uinfo) {
&$first_print($text{'disable_unix'});
&foreign_call($usermodule, "set_user_envs", $uinfo,
'MODIFY_USER', "", undef, $uinfo, "");
&foreign_call($usermodule, "making_changes");
$_[0]->{'disabled_oldpass'} = $uinfo->{'pass'};
$uinfo->{'pass'} = $uconfig{'lock_string'};
&foreign_call($usermodule, "modify_user", $uinfo, $uinfo);
&foreign_call($usermodule, "made_changes");
&$second_print($text{'setup_done'});
}
&foreign_call($usermodule, "unlock_user_files");
}
}
# enable_unix(&domain)
# Re-enable this domain's Unix user
sub enable_unix
{
if (!$_[0]->{'parent'}) {
&require_useradmin();
&foreign_call($usermodule, "lock_user_files");
local @allusers = &foreign_call($usermodule, "list_users");
local ($uinfo) = grep { $_->{'user'} eq $_[0]->{'user'} } @allusers;
if ($uinfo) {
&$first_print($text{'enable_unix'});
&foreign_call($usermodule, "set_user_envs", $uinfo,
'MODIFY_USER', "", undef, $uinfo, "");
&foreign_call($usermodule, "making_changes");
$uinfo->{'pass'} = $_[0]->{'disabled_oldpass'};
delete($_[0]->{'disabled_oldpass'});
&foreign_call($usermodule, "modify_user", $uinfo, $uinfo);
&foreign_call($usermodule, "made_changes");
&$second_print($text{'setup_done'});
}
&foreign_call($usermodule, "unlock_user_files");
}
}
# backup_unix(&domain, file)
# Backs up the users crontab file
sub backup_unix
{
local ($d, $file) = @_;
&foreign_require("cron", "cron-lib.pl");
local $cronfile = &cron::cron_file({ 'user' => $d->{'user'} });
&$first_print(&text('backup_cron'));
if (-r $cronfile) {
©_source_dest($cronfile, $file);
&$second_print($text{'setup_done'});
}
else {
&$second_print($text{'backup_cronnone'});
}
return 1;
}
# restore_unix(&domain, file, &options)
# Extracts the given tar file into a user's home directory
sub restore_unix
{
local ($d, $file, $opts) = @_;
&$first_print($text{'restore_unixuser'});
# Also re-set quotas
if (&has_home_quotas()) {
&set_server_quotas($_[0]);
}
# And update password and description
&require_useradmin();
local @allusers = &foreign_call($usermodule, "list_users");
local ($uinfo) = grep { $_->{'user'} eq $d->{'user'} } @allusers;
if ($uinfo && !$d->{'parent'}) {
local $olduinfo = { %$uinfo };
&foreign_call($usermodule, "lock_user_files");
$uinfo->{'real'} = $d->{'owner'};
local $enc = &foreign_call($usermodule, "encrypt_password",
$d->{'pass'});
$uinfo->{'pass'} = $enc;
&set_pass_change($uinfo);
&foreign_call($usermodule, "set_user_envs",
$uinfo, 'MODIFY_USER', $d->{'pass'}, undef, $olduinfo);
&foreign_call($usermodule, "making_changes");
&foreign_call($usermodule, "modify_user", $uinfo, $uinfo);
&foreign_call($usermodule, "made_changes");
&foreign_call($usermodule, "lock_user_files");
}
&$second_print($text{'setup_done'});
# Copy cron jobs file
if (-r $file) {
&$first_print($text{'restore_cron'});
&foreign_require("cron", "cron-lib.pl");
©_source_dest($file, $cron::cron_temp_file);
&cron::copy_crontab($d->{'user'});
&$second_print($text{'setup_done'});
}
return 1;
}
# bandwidth_unix(&domain, start, &bw-hash)
# Updates the bandwidth count for FTP traffic by the domain's unix user, and
# any mail users with FTP access
sub bandwidth_unix
{
local $log = $config{'bw_ftplog'} || &get_proftpd_log();
if ($log) {
local @users;
if (!$_[0]->{'parent'}) {
# Only do the domain owner if this is the parent domain, to
# avoid double-counting in subdomains
push(@users, $_[0]->{'user'});
}
foreach $u (&list_domain_users($_[0], 0, 1, 1, 1)) {
push(@users, $u->{'user'}) if ($u->{'unix'});
}
return &count_ftp_bandwidth($log, $_[1], $_[2], \@users, "ftp",
$config{'bw_ftplog_rotated'});
}
else {
return $_[1];
}
}
# show_template_unix(&tmpl)
# Outputs HTML for editing unix-user-related template options
sub show_template_unix
{
local ($tmpl) = @_;
# Quota-related defaults
print &ui_table_row(&hlink($text{'tmpl_quotatype'}, "template_quotatype"),
&ui_radio("quotatype", $tmpl->{'quotatype'},
[ $tmpl->{'default'} ? ( ) : ( [ "", $text{'default'} ] ),
[ "hard", $text{'tmpl_hard'} ],
[ "soft", $text{'tmpl_soft'} ] ]));
print &ui_table_row(&hlink($text{'tmpl_quota'}, "template_quota"),
&none_def_input("quota", $tmpl->{'quota'}, $text{'tmpl_quotasel'}, 1,
0, undef, [ "quota", "quota_units" ])."\n".
"a_input("quota", $tmpl->{'quota'} eq "none" ?
"" : $tmpl->{'quota'}, "home"));
print &ui_table_row(&hlink($text{'tmpl_uquota'}, "template_uquota"),
&none_def_input("uquota", $tmpl->{'uquota'}, $text{'tmpl_quotasel'}, 1,
0, undef, [ "uquota", "uquota_units" ])."\n".
"a_input("uquota", $tmpl->{'uquota'} eq "none" ?
"" : $tmpl->{'uquota'}, "home"));
print &ui_table_row(&hlink($text{'tmpl_defmquota'}, "template_defmquota"),
&none_def_input("defmquota", $tmpl->{'defmquota'}, $text{'tmpl_quotasel'},
0, 0, $text{'form_unlimit'},
[ "defmquota", "defmquota_units" ])."\n".
"a_input("defmquota", $tmpl->{'defmquota'} eq "none" ?
"" : $tmpl->{'defmquota'}, "home"));
# Domain owner primary group
print &ui_table_row(&hlink($text{'tmpl_ugroup'}, "template_ugroup_mode"),
&none_def_input("ugroup", $tmpl->{'ugroup'}, $text{'tmpl_ugroupsel'},
0, 0, undef, [ "ugroup" ])."\n".
&ui_textbox("ugroup", $tmpl->{'ugroup'} eq "none" ?
"" : $tmpl->{'ugroup'}, 13)."\n".
&group_chooser_button("ugroup", 0, 1));
}
# parse_template_unix(&tmpl)
# Updates unix-user-related template options from %in
sub parse_template_unix
{
local ($tmpl) = @_;
# Save quota-related defaults
$tmpl->{'quotatype'} = $in{'quotatype'};
$tmpl->{'quota'} = &parse_none_def("quota");
if ($in{"quota_mode"} == 2) {
$in{'quota'} =~ /^[0-9\.]+$/ || &error($text{'tmpl_equota'});
$tmpl->{'quota'} = "a_parse("quota", "home");
}
$tmpl->{'uquota'} = &parse_none_def("uquota");
if ($in{"uquota_mode"} == 2) {
$in{'uquota'} =~ /^[0-9\.]+$/ || &error($text{'tmpl_euquota'});
$tmpl->{'uquota'} = "a_parse("uquota", "home");
}
$tmpl->{'defmquota'} = &parse_none_def("defmquota");
if ($in{"defmquota_mode"} == 2) {
$in{'defmquota'} =~ /^[0-9\.]+$/ || &error($text{'tmpl_edefmquota'});
$tmpl->{'defmquota'} = "a_parse("defmquota", "home");
}
# Save domain owner primary group option
$tmpl->{'ugroup'} = &parse_none_def("ugroup");
if ($in{"ugroup_mode"} == 2) {
getgrnam($in{'ugroup'}) || &error($text{'tmpl_eugroup'});
}
}
# get_unix_shells()
# Returns a list of tuples containing shell types and paths, like :
# [ 'nologin', '/dev/null' ], [ 'ftp', '/bin/false' ], [ 'ssh', '/bin/sh' ]
sub get_unix_shells
{
# Read FTP-capable shells
local @rv;
local $_;
local @shells;
open(SHELLS, "/etc/shells");
while(<SHELLS>) {
s/\r|\n//g;
s/#.*$//;
push(@shells, $_) if (/\S/);
}
close(SHELLS);
local %shells = map { $_, 1 } @shells;
# Find no-login shells
local @nologin = ($config{'shell'}, '/dev/null', '/sbin/nologin',
'/bin/nologin', '/sbin/noshell', '/bin/noshell');
push(@rv, map { [ 'nologin', $_ ] } grep { !$shells{$_} } @nologin);
# Find a good FTP-capable shell
local @ftp = ( $config{'ftp_shell'}, '/bin/false', '/bin/true' );
push(@rv, map { [ 'ftp', $_ ] } grep { $shells{$_} } @ftp);
# Find FTP and SSH login shells
foreach my $s (keys %shells) {
if (&indexof($s, @nologin) < 0 && &indexof($s, @ftp) < 0) {
push(@rv, [ 'ssh', $s ]);
}
}
return @rv;
}
# build_denied_ssh_group([&new-domain])
# Update the deniedssh Unix group's membership list with all domain owners
# who don't get to login (based on their shell)
sub build_denied_ssh_group
{
local ($newd, $deld) = @_;
# First make sure the group exists
&require_useradmin();
local @allgroups = &list_all_groups();
local ($group) = grep { $_->{'group'} eq $denied_ssh_group } @allgroups;
return 0 if (!$group);
# Find domain owners who can't login
local @shells = &list_available_shells();
foreach my $d (&list_domains(), $newd) {
next if ($d->{'parent'} || !$d->{'unix'} || $d eq $deld);
local $user = &get_domain_owner($d);
local ($sinfo) = grep { $_->{'shell'} eq $user->{'shell'} } @shells;
if ($sinfo && $sinfo->{'id'} ne 'ssh') {
# On the denied list..
push(@members, $user->{'user'});
}
}
# Update the group
local $oldgroup = { %$group };
$group->{'members'} = join(",", &unique(@members));
if ($group->{'members'} ne $oldgroup->{'members'}) {
&foreign_call($group->{'module'}, "lock_user_files");
&foreign_call($group->{'module'}, "set_group_envs", $group,
'MODIFY_GROUP', $oldgroup);
&foreign_call($group->{'module'}, "making_changes");
&foreign_call($group->{'module'}, "modify_group", $oldgroup, $group);
&foreign_call($group->{'module'}, "made_changes");
&foreign_call($group->{'module'}, "unlock_user_files");
}
return 1;
}
# update_domain_owners_group([&new-domain], [&deleting-domain])
# If configure, update the member list of a secondary group which should
# contain all domain owners.
sub update_domain_owners_group
{
local ($newd, $deld) = @_;
return 0 if (!$config{'domains_group'});
# First make sure the group exists
&require_useradmin();
local @allgroups = &list_all_groups();
local ($group) = grep { $_->{'group'} eq $config{'domains_group'} } @allgroups;
return 0 if (!$group);
# Find domain owners with Unix logins
local @members;
foreach my $d (&list_domains(), $newd) {
if ($d->{'unix'} && $d ne $deld) {
push(@members, $d->{'user'});
}
}
# Update the group
local $oldgroup = { %$group };
$group->{'members'} = join(",", &unique(@members));
if ($group->{'members'} ne $oldgroup->{'members'}) {
&foreign_call($group->{'module'}, "lock_user_files");
&foreign_call($group->{'module'}, "set_group_envs", $group,
'MODIFY_GROUP', $oldgroup);
&foreign_call($group->{'module'}, "making_changes");
&foreign_call($group->{'module'}, "modify_group", $oldgroup, $group);
&foreign_call($group->{'module'}, "made_changes");
&foreign_call($group->{'module'}, "unlock_user_files");
}
}
sub startstop_unix
{
if (!$config{'ftp'} && &foreign_installed("proftpd")) {
# Even if the FTP feature is not enabled, show the proftpd start/stop
# buttons.
return &startstop_ftp();
}
return ( );
}
sub stop_service_unix
{
return &stop_service_ftp();
}
sub start_service_unix
{
return &start_service_ftp();
}
# delete_partial_group(&group)
# Deletes a group that may not have been created completely
sub delete_partial_group
{
local ($group) = @_;
eval {
local $main::error_must_die = 1;
local @allgroups = &list_all_groups();
local ($ginfo) = grep { $_->{'group'} eq $group->{'group'} &&
$_->{'module'} eq $usermodule } @allgroups;
if ($ginfo) {
&foreign_call($ginfo->{'module'}, "set_group_envs", $ginfo,
'DELETE_GROUP');
&foreign_call($ginfo->{'module'}, "making_changes");
&foreign_call($ginfo->{'module'}, "delete_group", $ginfo);
&foreign_call($ginfo->{'module'}, "made_changes");
}
};
}
# delete_partial_user(&user)
# Deletes a user that may not have been created completely
sub delete_partial_user
{
local ($user) = @_;
eval {
local $main::error_must_die = 1;
local @allusers = &list_all_users();
local ($uinfo) = grep { $_->{'user'} eq $user->{'user'} &&
$_->{'module'} eq $usermodule } @allusers;
if ($uinfo) {
&foreign_call($uinfo->{'module'}, "set_user_envs", $uinfo,
'DELETE_USER');
&foreign_call($uinfo->{'module'}, "making_changes");
&foreign_call($uinfo->{'module'}, "delete_user", $uinfo);
&foreign_call($uinfo->{'module'}, "made_changes");
}
};
}
$done_feature_script{'unix'} = 1;
1;
syntax highlighted by Code2HTML, v. 0.9.1