smeserver-lazy_admin_tools/root/usr/sbin/lat-dump

439 lines
15 KiB
Plaintext
Raw Normal View History

#!/usr/bin/perl -w
#==============================================================================
# lat-dump
# ========
# 0.9.0 (2004-09-08)
# (c)2003-2004 Altiplano bvba
#==============================================================================
package esmith;
use strict;
use esmith::config;
use esmith::db;
use esmith::util;
use Getopt::Long;
use Pod::Usage;
my %conf;
tie %conf, 'esmith::config';
my %accounts;
tie %accounts, 'esmith::config', '/home/e-smith/db/accounts';
my %hosts;
tie %hosts, 'esmith::config', '/home/e-smith/db/hosts';
my %domains;
tie %domains, 'esmith::config', '/home/e-smith/db/domains';
my %processmail;
# Really unsure of what this line does - John Bennett
tie %processmail, 'esmith::config', '/home/e-smith/db/processmail';
my ($Dump, $OutDir, $Hlp);
my $HostName = db_get(\%conf, 'SystemName');
#==============================================================================
# Main
#==============================================================================
# Analyze commandline options
GetOptions ("help" => \$Hlp,
"dump" => \$Dump,
"output-path=s" => \$OutDir);
if ( $Hlp ) { &PrintPod(9); exit; }
if ($OutDir) {
if ( ! -d $OutDir ) { die "Error: $OutDir is not a directory\n\a"; }
}
else
{ $OutDir = "./"; }
if ($Dump) {
print "Creating input files for the lat-toolkit... ";
&ReadUsers;
&ReadPseudonyms;
&ReadProcmail;
&ReadQuota;
&ReadGroups;
&ReadPPTP;
&ReadIbays;
&ReadDomains;
&ReadHosts;
&ReadShadow;
open (REST, "> $OutDir/lat-restore");
print REST "#!/bin/bash\n";
print REST "echo 'This script was automatically created by lat-dump and will recreate all user'\n";
print REST "echo 'accounts, ibays, etc on this server.'\n";
print REST "echo 'Do you want to continue (Y/N)?'\n";
print REST "read c\n";
print REST 'if [ $c = "y" ] || [ $c = "Y" ]; then'."\n";
print REST " /usr/sbin/lat-users -a -i=$HostName.Users\n";
print REST " /usr/sbin/lat-procmail -i=$HostName.Procmail\n";
print REST " /usr/sbin/lat-quota -i=$HostName.Quota\n";
print REST " /usr/sbin/lat-groups -a -i=$HostName.Groups\n";
print REST " /usr/sbin/lat-pptp -i=$HostName.PPTP\n";
print REST " /usr/sbin/lat-ibays -a -i=$HostName.Ibays\n";
print REST " /usr/sbin/lat-domains -a -i=$HostName.Domains\n";
print REST " /usr/sbin/lat-hosts -a -i=$HostName.Hosts\n";
print REST " /usr/sbin/lat-pseudonyms -a -i=$HostName.Pseudonyms\n";
print REST " /usr/sbin/lat-shadow -a -i=$HostName.shadow\n";
print REST "else\n";
print REST " echo 'Action cancelled!'\n";
print REST "fi\n";
close(REST);
chmod 0750, "$OutDir/lat-restore";
print "\nDone!\n";
print "Use lat-restore to recreate the accounts, ibays, etc on a different server \nor on a clean install.\n";
}
else { &PrintPod(1); exit; }
#==============================================================================
# Subroutines
#==============================================================================
sub ReadShadow {
open(BACACC, "> $OutDir/$HostName.shadow");
print BACACC "#--------------------------------#\n";
print BACACC "#User |Encrypted Password |\n";
print BACACC "#--------------------------------#\n";
use esmith::ConfigDB;
use esmith::AccountsDB;
my $adb = esmith::AccountsDB->open_ro();
foreach my $user ($adb->users)
{
my %properties = $user->props;
my $key = $user->key;
# lecture shadow
open(ACC, "< /etc/shadow") || die "Can't find /etc/shadow.\a\n";
my $line = "";
while (<ACC>){
$line = $_;
if($line =~ /^$key:(.*):(.*):(.*):(.*):(.*):(.*):(.*):$/){
print BACACC $key.(' ' x (12 - length($key)));
print BACACC " |";
print BACACC $1."\n";
}
}
close(ACC);
}
}
#==============================================================================
sub ReadUsers {
my @fldinf = ("User", 12,
"FirstName", 10,
"LastName", 15,
"Password", 8,
"Dept", 15,
"Company", 15,
"Street", 15,
"City", 20,
"Phone", 16,
"EmailForward", 12,
"ForwardAddress", 30,
"Uid", 5);
&PrintDump("Users", "user", "accounts", \%accounts, @fldinf);
}
#==============================================================================
sub ReadQuota {
my @fldinf = ("User", 30,
"MaxBlocksSoftLim", 16,
"MaxBlocks", 16);
&PrintDump("Quota", "user", "accounts", \%accounts, @fldinf);
}
#==============================================================================
sub ReadDomains {
my @fldinf = ("Domain", 30,
"Description", 23,
"Content", 12);
&PrintDump("Domains", "domain", "domains", \%domains, @fldinf);
}
#==============================================================================
sub ReadIbays {
my @fldinf = ("User", 12,
"Name", 23,
"Group", 12,
"UserAccess", 20,
"PublicAccess", 12,
"Password", 8,
"CgiBin", 9,
"Uid", 5);
&PrintDump("Ibays", "ibay", "accounts", \%accounts, @fldinf);
}
#==============================================================================
sub ReadPPTP {
my @fldinf = ("PPTPAccess", 10);
open(ACC, "< /home/e-smith/db/accounts") || die "Can't find /home/e-smith/db/accounts.\a\n";
my @accounts = sort(grep(/\=user\|/, <ACC>));
close(ACC);
open(BACACC, "> $OutDir/$HostName.PPTP");
print BACACC "#-------------------------#\n";
print BACACC "#User |PPTP Access |\n";
print BACACC "#-------------------------#\n";
foreach (@accounts) {
$_ =~ /\=user\|/;
my $AccName = $`;
print BACACC $AccName.(' ' x (12 - length($AccName)));
my $SMEvalue = db_get_prop(\%accounts,$AccName,"PPTPAccess");
if ( ! $SMEvalue) { $SMEvalue = "off" }
print BACACC " |";
print BACACC $SMEvalue."\n";
}
close(BACACC);
}
#==============================================================================
sub ReadPseudonyms {
open(ACC, "< /home/e-smith/db/accounts") || die "Can't find /home/e-smith/db/accounts.\a\n";
my @accounts = sort(grep(/\=user\|/i, <ACC>));
close(ACC);
push(@accounts,"admin=user|");
open(ACC, "< /home/e-smith/db/accounts") || die "Can't find /home/e-smith/db/accounts.\a\n";
my @pseudonyms = grep(/\=pseudonym\|/i, <ACC>);
close(ACC);
open(BACACC, "> $OutDir/$HostName.Pseudonyms");
print BACACC "#".('-' x 78)."#\n";
print BACACC "#User |Pseudonyms".(' ' x 55)."|\n";
print BACACC "#".('-' x 78)."#\n";
foreach (@accounts) {
if ($_ =~ /\=user\|/) {
my $AccName = $`;
my $pseudolist;
foreach (@pseudonyms) {
my $psinfo = $_;
$psinfo =~ /\|Account\|/i;
my $owner = $'; chomp($owner);
if ($AccName eq $owner) {
if ($psinfo =~ /\=pseudonym\|/i) { $pseudolist .= " | ".$`; }
}
}
if ($pseudolist) {
print BACACC $AccName.(' ' x (12 - length($AccName))).$pseudolist."\n";
}
}
}
close(BACACC);
}
#==============================================================================
sub ReadGroups {
my @finfo = ("Group", 12,
"Description", 30,
"Gid", 5,
"Members", 25);
my $nm = "group";
open(ACC, "< /home/e-smith/db/accounts") || die "Can't find /home/e-smith/db/accounts.\a\n";
my @accounts = sort(grep(/\=group\|/, <ACC>));
close(ACC);
open(BACACC, "> $OutDir/$HostName.Groups");
my $Header= "#$finfo[0]".(' ' x ($finfo[1] - 1 - length($finfo[0])))." |";
for (my $cnt=2; $cnt<$#finfo; $cnt=$cnt+2) {
$Header .= $finfo[$cnt].(' ' x ($finfo[$cnt+1] - length($finfo[$cnt])))." |";
}
print BACACC "#".("-" x (length($Header)-2))."#\n";
print BACACC $Header."\n";
print BACACC "#".("-" x (length($Header)-2))."#\n";
foreach (@accounts) {
$_ =~ /\=group\|/;
my $AccName = $`;
print BACACC $AccName.(' ' x ($finfo[1] - length($AccName)));
my $cnt;
for ($cnt=2; $cnt<$#finfo-2; $cnt=$cnt+2) {
my $SMEvalue = db_get_prop(\%accounts,$AccName,$finfo[$cnt]);
if ( ! $SMEvalue) { $SMEvalue = " " }
print BACACC " |";
print BACACC $SMEvalue.(' ' x ($finfo[$cnt+1] - length($SMEvalue)));
}
my $members = db_get_prop(\%accounts, $AccName, $finfo[$cnt]);
$members =~ s/,/ \|/g;
print BACACC " |$members\n";
}
close(BACACC);
}
#==============================================================================
sub ReadProcmail {
my @finfo = ("User", 12,
"Status", 8,
"deldups", 7,
"loglevel", 8,
"mode", 6);
open(ACC, "< /home/e-smith/db/accounts") || die "Can't find /home/e-smith/db/accounts.\a\n";
my @accounts = sort(grep(/\=user\|/, <ACC>));
close(ACC);
open(BACACC, "> $OutDir/$HostName.Procmail");
my $Header= "#User |";
for (my $cnt=2; $cnt<$#finfo; $cnt=$cnt+2) {
$Header .= $finfo[$cnt].(' ' x ($finfo[$cnt+1] - length($finfo[$cnt])))." |";
}
print BACACC "#".("-" x (length($Header)-2))."#\n";
print BACACC $Header."\n";
print BACACC "#".("-" x (length($Header)-2))."#\n";
foreach (@accounts) {
$_ =~ /\=user\|/;
my $AccName = $`;
print BACACC $AccName.(' ' x ($finfo[1] - length($AccName)));
if (db_get_prop(\%accounts, $AccName, "EmailForward") =~ m/procmail/i)
{ print BACACC " |enabled " }
else { print BACACC " |disabled" }
for (my $cnt=4; $cnt<$#finfo; $cnt=$cnt+2) {
my $SMEvalue = db_get_prop(\%processmail, $AccName, $finfo[$cnt]);
if ( ! $SMEvalue) { $SMEvalue = " " }
print BACACC " |";
print BACACC $SMEvalue.(' ' x ($finfo[$cnt+1] - length($SMEvalue)));
}
print BACACC "\n";
}
close(BACACC);
}
#==============================================================================
sub ReadHosts {
my @finfo = ("HostType", 8,
"Visibility", 10,
"InternalIP", 15,
"ExternalIP", 15,
"MACAddress", 17);
open(ACC, "< /home/e-smith/db/hosts") || die "Can't find /home/e-smith/db/hosts.\a\n";
my @accounts = sort(grep(/\=host\|/, <ACC>));
close(ACC);
open(BACACC, "> $OutDir/$HostName.Hosts");
my $Header= "#Hosts |";
$Header .= "Domainname |";
for (my $cnt=0; $cnt<$#finfo; $cnt=$cnt+2) {
$Header .= $finfo[$cnt].(' ' x ($finfo[$cnt+1] - length($finfo[$cnt])))." |";
}
print BACACC "#".("-" x (length($Header)-2))."#\n";
print BACACC $Header."\n";
print BACACC "#".("-" x (length($Header)-2))."#\n";
foreach (@accounts) {
$_ =~ /\=host\|/;
my $AccName = $`;
$AccName =~ m/\./;
$AccName = $`;
my $Domain = $';
print BACACC $AccName.(' ' x (12 - length($AccName)))." |";
print BACACC $Domain.(' ' x (35 - length($Domain)));
for (my $cnt=0; $cnt<$#finfo; $cnt=$cnt+2) {
my $SMEvalue = db_get_prop(\%hosts,"$AccName.$Domain",$finfo[$cnt]);
if ( ! $SMEvalue) { $SMEvalue = " " }
print BACACC " |";
print BACACC $SMEvalue.(' ' x ($finfo[$cnt+1] - length($SMEvalue)));
}
print BACACC "\n";
}
close(BACACC);
}
#==============================================================================
# Print lat-info in a nice format
sub PrintDump {
my ($out, $nm, $src, $dbpointer, @finfo) = @_;
open(ACC, "< /home/e-smith/db/$src") || die "Can't find /home/e-smith/db/$src.\a\n";
my @accounts = sort(grep(/\=$nm\|/, <ACC>));
close(ACC);
open(BACACC, "> $OutDir/$HostName.$out");
my $Header= "#$finfo[0]".(' ' x ($finfo[1] - 1 - length($finfo[0])))." |";
for (my $cnt=2; $cnt<$#finfo; $cnt=$cnt+2) {
$Header .= $finfo[$cnt].(' ' x ($finfo[$cnt+1] - length($finfo[$cnt])))." |";
}
print BACACC "#".("-" x (length($Header)-2))."#\n";
print BACACC $Header."\n";
print BACACC "#".("-" x (length($Header)-2))."#\n";
foreach (@accounts) {
$_ =~ /\=$nm\|/;
my $AccName = $`;
print BACACC $AccName.(' ' x ($finfo[1] - length($AccName)));
for (my $cnt=2; $cnt<$#finfo; $cnt=$cnt+2) {
my $SMEvalue = db_get_prop($dbpointer,$AccName,$finfo[$cnt]);
if ( ! $SMEvalue) { $SMEvalue = " " }
print BACACC " |";
print BACACC $SMEvalue.(' ' x ($finfo[$cnt+1] - length($SMEvalue)));
}
print BACACC "\n";
}
close(BACACC);
}
#==============================================================================
# Print the pod text as a help screen
sub PrintPod {
my ($verbose, $message) = @_;
pod2usage(-verbose => $verbose, -message => $message, -exitval => 64);
}
#==============================================================================
=pod
=head1 NAME
B<lat-dump> - The lazy administrator's tool to extract config info
=head1 DESCRIPTION
Creates input-files for the lat-toolkit, based on the current configuration of the SME server (5.x/6.x). The information is extracted from the /home/e-smith/db/* databases.
The resulting input-files can be used to replicate user accounts, ibays, etc on a different SME server, or recreate them on a clean install. To facilitate the restoring/replicating, the lat-restore script is automatically created. This will launch the various lat-tools in the right sequence.
=head1 SYNOPSIS
B<lat-config> [options]
=head1 OPTIONS
The following options are supported:
=over 4
=item B<-d>, B<--dump>
Create input files
=item B<-h>, B<--help>
Extended help for this tool
=item B<-o=/path/>, B<--output-dir=/path/>
Directory where the configuration files should be stored. If omitted, the current directory is used.
=back
=head1 EXAMPLES
B<lat-dump -d -o=/var/tmp>
Creates the configuration files and writes them to /var/tmp.
=head1 SEE ALSO
lat-users(8), lat-group(8), lat-pseudonyms(8), lat-ibays(8), lat-quota(8), lat-domains(8), lat-hosts(8), lat-procmail(8), lat-pptp(8)
=head1 VERSION
Version 0.9.0 (2004-09-08). The latest version is hosted at B<http://www.contribs.org/contribs/mblotwijk/>
=head1 COPYRIGHT
(c)2003-2004, Altiplano bvba (B<http://www.altiplano.be>). Released under the terms of the GNU license.
=head1 BUGS
Please report bugs to <Bugs@Altiplano.Be>
=cut
#==============================================================================