initial commit of file from CVS for smeserver-lazy_admin_tools on Sat Sep 7 20:29:45 AEST 2024
This commit is contained in:
438
root/usr/sbin/lat-dump
Normal file
438
root/usr/sbin/lat-dump
Normal file
@@ -0,0 +1,438 @@
|
||||
#!/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
|
||||
|
||||
#==============================================================================
|
Reference in New Issue
Block a user