#!/usr/bin/perl
####### meta-verify-raq3.pl
#
# system & database verification and integrity check utility
#
# Duncan Laurie (duncan@cobalt.com)
# (c) 2000 Cobalt Networks, Inc
#
#
####### OPERATION
#
# meta-verify-raq3.pl -u|s -a|i|d [-v] [-h]
#
# -u users
# -s virtual sites
#
# -i repair invalid
# -a verify all valid
# -d drop table
#
# -v increase warning level
# -h usage help
#
#
####### USES
#
# - Verify and repair virtual sites.
# - Verify and repair user accounts.
# - Maintain intergrity of the RaQ3 system configuration files.
# - Ensure coherency between System and Meta/postgreSQL backend.
#
#
####### DESCRIPTION
#
# The RaQ3 (all varieties pre Update 2.0) contains a bug w.r.t. handling
# single quote characters in vacation messages and usernames that
# begin with a decimal digit. The result of this bug is that some or even
# all of your users could become "detached" from the Web GUI -- they will
# exist on the system but not show up in the Admin interface.
#
# This script attempts to detect and repair coherency problems that may
# result from this bug. It will find invalid (detached) users and
# present them as Meta object which can be saved to the postgreSQL backend.
#
# UPDATE: as of version 2.0 this can now rebuild the virtual site table.
#
#
####### REQUIREMENTS
#
# RaQ3 / RaQ3i / RaQ3-ja
#
#
####### CHANGELOG
#
# version 2.1 (Apr 18 2000)
# - added 'Y' option to say yes to all
#
# version 2.0 (Mar 01 2000)
# - now has support for rebuilding the virtual site list
# - command line options have changed
#
# version 1.2 (Feb 16 2000)
# - don't show conflict on self->self aliases
# - vacationmsg field is now blank
#
# version 1.1 (Feb 04 2000)
# - fix display of user info that is longer than page width
# - fix alias handling
# - verifies system is RaQ3 and user is root
#
# version 1.0 (Feb 03 2000)
# - initial release
# - fix incorrect reporting of frontpage state
#
# version 0.9 (Feb 02 2000)
# - verify valid user accounts, prompt database update when changes detected
# - prompts for and allows database deletion of sites that do not exist in
# the system configuration
# - fix int() conversion & mismatched parens
#
# version 0.8 (Feb 01 2000)
# - @{ union,intersect,symmetric difference } for database/system user lists
# - detect invalid system users correctly
#
# version 0.7 (Feb 01 2000)
# - meta object containing all user fields, completed with information from
# current system configuration and state information
#
# version 0.1 (Jan 31 2000)
# - initial creation
#
#
#######
# verify that this is a 3000R
my $build_file = "/etc/build";
if (-e $build_file) {
if (system("/bin/grep", "-q", "3[01]00R", "$build_file")) {
die("\nThis program is only for the RaQ3!\n\n");
}
} else {
die("\nThis program is only for the RaQ3!\n\n");
}
# verify that we are root
if ($< != 0) {
die("\nThis program must be run as root!\n\n");
}
require Cobalt::Meta;
require Cobalt::User;
require Cobalt::Vacation;
require Cobalt::Email;
require Cobalt::List;
require Cobalt::Fpx;
require Cobalt::Ftp;
require Cobalt::BandWidth;
require Cobalt::Quota;
use Getopt::Std;
use IO::File;
# program info
use vars qw($Title $Product $Version $Author $Company);
$Product = "meta-verify.pl";
$Title = '"system & database verifier"';
$Author = "Duncan Laurie (duncan\@cobalt.com)";
$Company = "(c) 2000 Cobalt Networks, Inc";
$Version = "2.2";
# program header
printf("\n");
printf("%s\n", $Product);
printf("%s\n", $Title);
printf("version %s\n", $Version);
printf("%s\n", $Author);
printf("%s\n", $Company);
# global variables
use vars qw($e %eCOUNT @eALL @eGOOD @eBAD);
use vars qw(@eFIELDS @eARRAYS);
use vars qw(@all_DB @all_SYS $entryX $entry $entryTYPE);
use vars qw($opt_h $opt_u $opt_s $opt_v $opt_a $opt_i $opt_d $opt_l $Verbose);
use vars qw($login $message $field $DB_field $SYS_field);
# format for output of messages
format PRINT_MSG =
| ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
$message
~ ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<...
$message
.
# format for output of messages
format PRINT_ENTRY =
@>>>>>>>>>>>>>> | ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
$login, $message
~ ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<...
$message
.
# format for output when handling entry errors
format PRINT_ENTRY_ERROR =
@>>>>>>>>>>>>>> | ERROR ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
$login, $message
~ ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<...
$message
.
# format for output when processing
format PRINT_FIELD =
@>>>>>>>>>>>>>> | @>>>>>>>>>>>>> = ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
$login, $field, $message
~ ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
$message
~ ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<...
$message
.
# format for error output when comparing meta+system fields
format PRINT_FIELD_ERROR =
@>>>>>>>>>>>>>> | ERROR IN @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
$login, $field
| DATABASE ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
$DB_field
~ | ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
$DB_field
~ | ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<...
$DB_field
| SYSTEM ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
$SYS_field
~ | ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
$SYS_field
~ | ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<...
$SYS_field
.
use strict;
# command-line arguments, verbose level
getopts("suvaihdl");
# usage help
if ($opt_h)
{
printf("\n");
printf(" usage: %s -u|s -a|i|d [-v] [-h]\n", $Product);
printf("\n");
printf(" -l reset /home/sites symlinks\n");
printf(" -u verify users\n");
printf(" -s verify virtual sites\n");
printf("\n");
printf(" -i repair invalid\n");
printf(" -a verify valid\n");
printf(" -d drop table\n");
printf("\n");
printf(" -v increase warning level\n");
printf(" -h usage help\n");
printf("\n");
exit 1;
}
$Verbose = ($opt_v) ? 1 : 0;
if ($opt_l) {
# reset virtual site symlinks with
# entries from /etc/httpd/conf/httpd.conf
my $root = "/home/sites";
my $httpd_conf = "/etc/httpd/conf/httpd.conf";
my($vpath,$vhost,$host);
unless (-s $httpd_conf) {
printf("ERROR: $httpd_conf not found\n");
exit 1;
}
my $htconf = new IO::File "$httpd_conf";
unless (defined $htconf) {
printf("ERROR: unable to open $httpd_conf: $!\n");
exit 1;
}
print "\n";
while (<$htconf>) {
if (m{^} ... m{^}) {
if (m{^DocumentRoot $root/([^/]+)/web}) {
$entry = $1;
$vpath = "$root/$entry";
}
elsif (m{^ServerName (.+)}) {
$host = $1;
$vhost = "$root/$host";
}
if (m{^}) {
next unless (-d $vpath);
unlink $vhost if (-e $vhost);
print_entry($host);
symlink $vpath, $vhost;
$vpath=$vhost="";
}
}
}
print "\n";
undef $htconf;
exit 0;
}
printf("\nchecking system+database coherency...\n");
if ($opt_u)
{
&setup_users();
}
elsif ($opt_s)
{
&setup_vsite();
}
else
{
printf("error\n - must specify users (-u) or virtual sites (-s)\n\n");
exit 1;
}
if ($opt_d)
{
printf("dropping database table...\n");
&Cobalt::Meta::drop($entryTYPE);
# {
# printf("ERROR - unable to drop database \"$entryTYPE\"\n\n");
# exit 1;
# }
printf("OK\n\n");
exit 0;
}
foreach $e (@all_DB, @all_SYS)
{
$eCOUNT{$e}++;
}
foreach $e (keys %eCOUNT)
{
# union -
# all in database or system
push(@eALL, $e);
if ($eCOUNT{$e} == 2)
{
# intersection -
# both in database and in system
push(@eGOOD, $e);
}
else
{
# symmetric difference -
# either not in database or not in system
push(@eBAD, $e);
}
}
# output NUMBERS
print "\n";
printf(" database | %d\n", scalar(@all_DB));
printf(" system | %d\n", scalar(@all_SYS));
printf(" total | %d\n", scalar(@eALL));
printf(" valid | %d\n", scalar(@eGOOD));
printf(" invalid | %d\n", scalar(@eBAD));
print "\n";
if ($opt_a)
{
printf("verifying %d VALID %s...\n\n", scalar(@eGOOD),
(($opt_s) ? "virtual site(s)" : "user(s)"));
&examine_valid(@eGOOD);
}
elsif ($opt_i)
{
printf("repairing %d INVALID %s...\n\n", scalar(@eBAD),
(($opt_s) ? "virtual site(s)" : "user(s)"));
&examine_invalid(@eBAD) if (scalar(@eBAD));
}
else
{
printf("error - must specify valid (-a) or invalid (-i)\n\n");
exit 1;
}
print "\n" unless ($Verbose);
printf("OK\n\n");
exit 0;
1;
sub print_msg
{
$message = "@_";
$~ = 'PRINT_MSG';
write();
}
sub print_entry
{
$message = "@_";
$login = "$entry";
$~ = 'PRINT_ENTRY';
write();
}
sub print_entry_error
{
$message = "(@_)";
$login = "$entry";
$~ = 'PRINT_ENTRY_ERROR';
write();
}
sub print_field
{
($field,$message) = (@_);
$login = "$entry";
$~ = 'PRINT_FIELD';
write();
}
sub print_field_error
{
($field,$DB_field,$SYS_field) = (@_);
$field = "($field)";
$DB_field = "($DB_field)";
$SYS_field = "($SYS_field)";
$login = "$entry";
$~ = 'PRINT_FIELD_ERROR';
write();
}
# examine_invalid ()
#
# check the LIST for invalid
# correct the problem if possible
#
# arg: list to check
#
sub examine_invalid ()
{
my (@eLIST) = (@_);
my $yes = 0;
foreach $entry (@eLIST)
{
my $inDB = 0;
my $inSYS = 0;
printf("\n");
# see if this entry exists in the database
if (grep(/\b$entry\b/, @all_DB))
{
$inDB = 1;
}
else
{
$inDB = 0;
&print_entry_error("entry does not exist in database");
}
# see if this entry exists in the system
&print_msg("retrieving information from system...") if ($Verbose);
$entryX = &build_system("$entry");
if ($entryX)
{
$inSYS = 1;
}
else
{
&print_entry_error("does not exist in system");
$inSYS = 0;
}
# in both system and database
# this should never happen
if ($inSYS && $inDB)
{
&print_entry_error("entry is already valid");
$entryX->DESTROY();
next;
}
# in system but not database
if ($inSYS)
{
my $input;
# confirm add
while ($input !~ /^[Yyn]/ && !$yes)
{
printf(" | - save ALL\n");
printf(" | - save entry to database\n");
printf(" | - do NOT save entry to database\n");
printf(" | - view info obtained from system\n");
printf(" | save? [Yynv] ");
$input = ;
$yes++ if ($input =~ /^Y/);
# print info
if ($input =~ /^v/)
{
$Verbose++;
$entryX->DESTROY();
$entryX = &build_system("$entry");
$Verbose--;
}
}
# always give the chance to bail
next if ($input =~ /^n/);
# save
unless ($entryX->save())
{
&print_entry_error("unable to save");
$entryX->DESTROY();
next;
}
&print_entry("saved");
$entryX->DESTROY();
next;
}
# in database but not system
if ($inDB)
{
my $input = '';
my $entryY = Cobalt::Meta->new("type" => "$entryTYPE");
# confirm database entry delete
while ($input !~ /^[yn]/)
{
printf(" | - remove database entry\n");
printf(" | - do NOT remove database entry\n");
printf(" | remove? [yn] ");
$input = ;
}
# always give the chance to bail
next if ($input =~ /^n/);
# delete entry
$entryY->retrieve("$entry");
unless ($entryY->delete())
{
&print_entry_error("unable to remove");
$entryY->DESTROY();
next;
}
$entryY->DESTROY();
&print_entry("removed");
next;
}
# not in database or system
&print_entry_error("entry not in database OR system");
next;
}
return;
}
# examine_valid ()
#
# check the LIST for valid and verify
# coherency of fields between system and database
#
# correct the problem if possible
#
# arg: list to check
#
sub examine_valid ()
{
my (@eLIST) = (@_);
foreach $entry (@eLIST)
{
# this entry from the database
my $entry_DB = (Cobalt::Meta->new("type" => "$entryTYPE"));
unless ($entry_DB->retrieve("$entry"))
{
&print_entry_error("entry non-existant in database");
next;
}
# get info from the system
my $entry_SYS = &build_system("$entry");
unless ($entry_SYS)
{
&print_entry_error("entry does not exist in system");
next;
}
# compare fields
my $errcount = 0;
foreach my $fld (@eFIELDS)
{
if ($entry_DB->{$fld} ne $entry_SYS->{$fld})
{
$errcount++;
&print_field_error($fld, $entry_DB->{$fld}, $entry_SYS->{$fld});
}
}
foreach my $fld (@eARRAYS)
{
my ($e,@aDB,@aSYS,%count,@diff);
# turn flat string into list
@aDB = split(' ', $entry_DB->{$fld});
@aSYS = split(' ', $entry_SYS->{$fld});
# compute difference of lists
foreach $e (@aDB, @aSYS) { $count{$e}++ }
foreach $e (keys %count) { push (@diff, $e) unless ($count{$e} == 2) }
# if difference then error
if (scalar(@diff))
{
$errcount++;
&print_field_error($fld, join(', ', @aDB), join(', ', @aSYS));
}
}
if ($errcount)
{
my $input;
# confirm database update
while ($input !~ /^[yn]/)
{
printf(" | - update database info for entry\n");
printf(" | - do NOT update database\n");
printf(" | update? [yn] ");
$input = ;
}
# always give the chance to bail
if ($input =~ /^n/)
{
print "\n";
next;
}
# save
unless ($entry_SYS->save())
{
&print_entry_error("unable to save");
print "\n";
}
else
{
&print_entry("updated");
print "\n";
}
}
else
{
&print_entry("ok");
print "\n" if ($Verbose);
}
$entry_DB->DESTROY();
$entry_SYS->DESTROY();
}
return;
}
sub setup_users ()
{
$entryTYPE = "users";
# some global variables
# user fields to compare when verifying all users
@eFIELDS = ("name", "fullname", "uid", "vsite", "quota",
"vacation", "admin", "shell", "apop", "fpx", "suspend");
# these fields are to be treated as arrays
# where order does NOT matter
@eARRAYS = ("forward", "aliases");
# the global database views and Meta objects
$entryX = Cobalt::Meta->new("type" => "users");
@all_DB = $entryX->getall();
@all_SYS = Cobalt::User::user_list();
# remove admin from both sets
@all_SYS = grep !/\bdefault\b/, @all_SYS;
@all_SYS = grep !/\badmin\b/, @all_SYS;
@all_DB = grep !/\bdefault\b/, @all_DB;
@all_DB = grep !/\badmin\b/, @all_DB;
if ($Verbose)
{
print "\n";
foreach $e (@all_DB) { &print_field("db user", $e); }
foreach $e (@all_SYS) { &print_field("sys user", $e); }
print "\n";
}
}
sub setup_vsite ()
{
$entryTYPE = "vsite";
# some global variables
# user fields to compare when verifying all users
@eFIELDS = ("emaildomain", "name", "suspend", "fqdn", "quota",
"ftp", "fpx", "ssi", "ssl", "cgi", "ipaddr",
"webdomain", "bwlimit", "domain", "hostname");
# these fields are to be treated as arrays
# where order does NOT matter
@eARRAYS = ();
# the global database views and Meta objects
$entryX = Cobalt::Meta->new("type" => "vsite");
@all_DB = $entryX->getall();
map { push @all_SYS, @$_[2]; } (Cobalt::Vsite::vsite_list());
# remove from both sets
@all_SYS = grep !/\bdefault\b/, @all_SYS;
@all_DB = grep !/\bdefault\b/, @all_DB;
if ($Verbose)
{
print "\n";
foreach $e (@all_DB) { &print_field("db vsite", $e); }
foreach $e (@all_SYS) { &print_field("sys vsite", $e); }
print "\n";
}
}
sub build_system ()
{
my $ebuild = shift;
return unless ($ebuild);
if ($entryTYPE eq "users")
{
return build_user_system($ebuild);
}
elsif ($entryTYPE eq "vsite")
{
return build_vsite_system($ebuild);
}
return;
}
sub build_vsite_system ()
{
my $site = shift;
return unless ($site);
my(@tmpARRAY);
my($newVSITE) = Cobalt::Meta->new("type" => "vsite");
$newVSITE->put("name" => "$site",
# network info
"ipaddr" => "",
"hostname" => "",
"domain" => "",
"fqdn" => "",
# configuration values
"maxusers" => 100,
"quota" => 1000,
"ftpquota" => 20,
"ftpusers" => 10,
"gid" => 0,
# default options to off
"ftp" => "off",
"fpx" => "off",
"ssi" => "off",
"cgi" => "off",
"ssl" => "off",
"apop" => "off",
"shell" => "off",
"suspend" => "off",
"bwlimit" => "off",
"webdomain" => "off",
"emaildomain" => "off",
# user defaults
"userlist_range" => 15,
"userlist_sort" => "name",
"user_namegen" => 0,
"user_quota" => 10,
"user_shell" => "off",
"user_fpx" => "off",
"user_apop" => "off"
);
&print_field("group", $newVSITE->get("name")) if ($Verbose);
# verify the group existance
unless (Cobalt::Group::group_exist("$site"))
{
&print_entry_error("group does not exist");
return;
}
# retrieve network info from httpd.conf
my($ipaddr,$fqdn) = (Cobalt::Vsite::vsite_get_bygroup("$site"))[0,1];
unless ($ipaddr && $fqdn)
{
&print_entry_error("does not exist in apache configuration");
return;
}
$newVSITE->put("ipaddr", "$ipaddr");
&print_field("ipaddr", $newVSITE->get("ipaddr")) if ($Verbose);
$newVSITE->put("fqdn", "$fqdn");
&print_field("fqdn", $newVSITE->get("fqdn")) if ($Verbose);
# parse fqdn for hostname+domain
unless ($fqdn =~ /([-\w]+)\.([-\w\.]+)/)
{
&print_entry_error("unable to split \"$fqdn\" into hostname+domain");
return;
}
my($hostname,$domain) = ($1,$2);
$newVSITE->put("hostname", "$1");
&print_field("hostname", $newVSITE->get("hostname")) if ($Verbose);
$newVSITE->put("domain", "$2");
&print_field("domain", $newVSITE->get("domain")) if ($Verbose);
# get the GID
$newVSITE->put("gid", (getgrnam("$site"))[2]);
&print_field("GID", $newVSITE->get("gid")) if ($Verbose);
# see if this has a serveralias for the domain (webdomain)
my($found) = 0;
if (Cobalt::Util::FILE_lock_r("/etc/httpd/conf/httpd.conf", *HTCONF))
{
while ()
{
if (m%^$% ... m%^$%) {
$found = 1 if (m%^DocumentRoot /home/sites/\Q$site\E/web$%);
if ($found)
{
last if (m%^$%);
if (m%^ServerAlias \Q$domain\E$%)
{
$newVSITE->put("webdomain", "on");
last;
}
}
}
}
Cobalt::Util::FILE_unlock(*HTCONF);
}
else
{
&print_entry_error("cannot open apache config file") if ($Verbose);
}
&print_field("web \@domain", $newVSITE->get("webdomain")) if ($Verbose);
# get emaildomain setting
my(%routes) = Cobalt::Email::mail_virtuser_list_route();
$newVSITE->put("emaildomain", exists($routes{"$domain"}) ? "on" : "off");
&print_field("email \@domain", $newVSITE->get("emaildomain")) if ($Verbose);
# get disk quota
my($quota) = (Cobalt::Quota::repquota("$site", 1))[1];
if ($quota > 0)
{
$newVSITE->put("quota", int(($quota * 1024) / 1048576));
}
&print_field("disk quota", $newVSITE->get("quota")) if ($Verbose);
# get anon ftp settings from proftpd config file
my($ftp,$ftpusers,$ftpquota) = Cobalt::Ftp::ftp_get_anonymous("$site");
if ($ftp)
{
$newVSITE->put("ftp", "on");
$newVSITE->put("ftpusers", $ftpusers);
if ($ftpquota > 0)
{
$newVSITE->put("ftpquota", int(($ftpquota * 1024) / 1048576));
}
}
&print_field("anonymous FTP", $newVSITE->get("ftp")) if ($Verbose);
# get suspend flag
$newVSITE->put("suspend", (Cobalt::Vsite::vsite_issuspend("$site")) ? "on" : "off");
&print_field("suspended", $newVSITE->get("suspend")) if ($Verbose);
# get frontpage settings
$newVSITE->put("fpx", (Cobalt::Fpx::fpx_get_web("$site")) ? "on" : "off");
&print_field("frontpage", $newVSITE->get("fpx")) if ($Verbose);
# get cgi settings
$newVSITE->put("cgi", (Cobalt::Vsite::vsite_get_cgis("$site")) ? "on" : "off");
&print_field("CGI scripts", $newVSITE->get("cgi")) if ($Verbose);
# get ssi settings
$newVSITE->put("ssi", (Cobalt::Vsite::vsite_get_ssi("$site")) ? "on" : "off");
&print_field("SSI scripts", $newVSITE->get("ssi")) if ($Verbose);
# get ssl settings
$newVSITE->put("ssl", (-f "/etc/httpd/ssl/$site") ? "on" : "off");
&print_field("SSL server", $newVSITE->get("ssl")) if ($Verbose);
# attempt to get bandwidth limit
$newVSITE->put("bwlimit", (Cobalt::BandWidth::bw_getip("$ipaddr") > 0) ? "on" : "off");
&print_field("bandwidth", $newVSITE->get("bwlimit")) if ($Verbose);
printf("\n") if ($Verbose);
return $newVSITE;
}
# build_user_system ()
#
# tries to build a Meta object of type "users"
# from information gathered by the system
#
# arg: login name
# ret: Meta object (type => users)
#
sub build_user_system ()
{
my $user = shift;
return unless ($user);
my (@tmpARRAY);
my $newUSER = Cobalt::Meta->new("type" => "users");
# get basic user info
my ($name,$uid,$fullname,$dir,$sh) = (getpwnam("$user"))[0,2,6,7,8];
unless ($name)
{
&print_entry_error("does not exist in password file");
return;
}
# determine virtual site from home directory path
my $vsite;
if ($dir =~ m|^/home/sites/home/users/|)
{
$vsite = "home";
}
elsif ($dir =~ m|^/home/sites/(site[0-9]+)/users/|)
{
$vsite = "$1";
}
else
{
&print_entry_error("invalid home directory");
return;
}
printf("\n") if ($Verbose);
# user name
$newUSER->put("name", "$name");
&print_field("user name", $name) if ($Verbose);
# full name
$newUSER->put("fullname", "$fullname");
$newUSER->put("altname", "");
&print_field("full name", $fullname) if ($Verbose);
# UID
$newUSER->put("uid", "$uid");
&print_field("UID", $uid) if ($Verbose);
# virtual site membership
$newUSER->put("vsite", "$vsite");
&print_field("virtual site", $vsite) if ($Verbose);
# disk quota
my($quota) = (Cobalt::Quota::repquota("$user"))[1];
$newUSER->put("quota", (($quota > 0) ? int(($quota * 1024) / 1048576) : 0));
&print_field("disk quota", $newUSER->get("quota")) if ($Verbose);
# email aliases
my $aliases = "";
@tmpARRAY = (Cobalt::Email::mail_virtuser_get_byuser("$user"));
if (scalar(@tmpARRAY))
{
# remove domains
my @oARRAY;
foreach (@tmpARRAY) {
if (/^([^@]+)\@.*/) {
push(@oARRAY, $1) unless($1 eq $user);
} else {
push(@oARRAY, $_);
}
}
$aliases = join(" ", @oARRAY);
}
$newUSER->put("aliases", "$aliases");
&print_field("email aliases", $aliases) if ($Verbose);
# email forwarding
@tmpARRAY = (Cobalt::List::alias_get_vacationless("$user"));
$newUSER->put("forward", ((scalar(@tmpARRAY) > 0) ? join(" ", @tmpARRAY) : "off"));
&print_field("email forward", $newUSER->get("forward")) if ($Verbose);
# virtual site administrator
@tmpARRAY = (Cobalt::User::user_list_groups("$user"));
$newUSER->put("admin", ((scalar(grep(/\b$vsite\b/, @tmpARRAY))) ? "on" : "off"));
&print_field("site admin", $newUSER->get("admin")) if ($Verbose);
# suspended user
$newUSER->put("suspend", ((Cobalt::User::user_issuspend("$user")) ? "on" : "off"));
&print_field("suspended", $newUSER->get("suspend")) if ($Verbose);
# telnet/shell access
$newUSER->put("shell", (($sh eq "/bin/bash") ? "on" : "off"));
&print_field("telnet/shell", $newUSER->get("shell")) if ($Verbose);
# authenticated pop3 (APOP)
$newUSER->put("apop", ((Cobalt::Email::mail_apop_isuser("$user")) ? "on" : "off"));
&print_field("secure POP3", $newUSER->get("apop")) if ($Verbose);
# frontpage extensions
@tmpARRAY = (Cobalt::Vsite::vsite_get_fpx("$vsite"));
$newUSER->put("fpx", ((scalar(grep(/\b$user\b/, @tmpARRAY))) ? "on" : "off"));
&print_field("frontpage", $newUSER->get("fpx")) if ($Verbose);
# email vacation responder
$newUSER->put("vacation", ((Cobalt::Vacation::vacation_get_on("$user")) ? "on" : "off"));
&print_field("vacation", $newUSER->get("vacation")) if ($Verbose);
$newUSER->put("vacationmsg", "");
printf("\n") if ($Verbose);
return $newUSER;
}