X-Git-Url: http://git.freeside.biz/gitweb/?p=freeside.git;a=blobdiff_plain;f=bin%2Fsvc_acct.export;h=dba4ac98dfd621da76318af61cbd6ccf969fb656;hp=073359587f5f304ec46014e1959423817a32cc65;hb=1f1190b8fb6d06852dbd16c6a288f9acd9cc83dd;hpb=1c14b1faec0f3f07a6d4190cf535b3ddb45075ce diff --git a/bin/svc_acct.export b/bin/svc_acct.export index 073359587..dba4ac98d 100755 --- a/bin/svc_acct.export +++ b/bin/svc_acct.export @@ -1,446 +1,54 @@ -#!/usr/bin/perl -w -# -# $Id: svc_acct.export,v 1.18 2001-04-22 01:56:15 ivan Exp $ -# -# Create and export password files: passwd, passwd.adjunct, shadow, -# acp_passwd, acp_userinfo, acp_dialup, users -# -# ivan@voicenet.com late august/september 96 -# (the password encryption bits were from melody) -# -# use a temporary copy of svc_acct to minimize lock time on the real file, -# and skip blank entries. -# -# ivan@voicenet.com 96-Oct-6 -# -# change users / acp_dialup file formats -# ivan@voicenet.com 97-jan-28-31 -# -# change priority (after copies) to 19, not 10 -# ivan@voicenet.com 97-feb-5 -# -# added exit if stuff is already locked 97-apr-15 -# -# rewrite ivan@sisd.com 98-mar-9 -# -# Changed 'password' to '_password' because Pg6.3 reserves this word -# Added code to create a FreeBSD style master.passwd file -# bmccane@maxbaud.net 98-Apr-3 -# -# don't export non-root 0 UID's, even if they get put in the database -# ivan@sisd.com 98-jul-14 -# -# Uses Idle_Timeout, Port_Limit, Framed_Netmask and Framed_Route if they -# exist; need some way to support arbitrary radius fields. also -# /var/spool/freeside/conf/ ivan@sisd.com 98-jul-26, aug-9 -# -# OOPS! added arbitrary radius fields (pry 98-aug-16) but forgot to say so. -# ivan@sisd.com 98-sep-18 -# -# $Log: svc_acct.export,v $ -# Revision 1.18 2001-04-22 01:56:15 ivan -# get rid of FS::SSH.pm (became Net::SSH and Net::SCP on CPAN) -# -# Revision 1.17 2001/02/21 23:48:19 ivan -# add icradius_secrets config file to export to a non-Freeside MySQL database for -# ICRADIUS -# -# Revision 1.16 2000/07/06 13:23:29 ivan -# tyop -# -# Revision 1.15 2000/07/06 08:57:28 ivan -# support for radius check attributes (except importing). poorly documented. -# -# Revision 1.14 2000/06/29 15:01:25 ivan -# another silly typo in svc_acct.export -# -# Revision 1.13 2000/06/28 12:37:28 ivan -# add support for config option textradiusprepend -# -# Revision 1.12 2000/06/15 14:07:02 ivan -# added ICRADIUS radreply table support, courtesy of Kenny Elliott -# -# Revision 1.11 2000/03/06 16:00:39 ivan -# sync up with working versoin -# -# Revision 1.2 1998/12/10 07:23:15 ivan -# use FS::Conf, need user (for datasrc) -# +#!/usr/bin/perl use strict; -use vars qw($conf); -use Fcntl qw(:flock); -use IO::Handle; -use DBI; -use FS::Conf; -use Net::SSH qw(ssh); -use Net::SCP qw(scp); -use FS::UID qw(adminsuidsetup datasrc dbh); -use FS::Record qw(qsearch fields); +use Text::CSV_XS; +use FS::UID qw(adminsuidsetup); +use FS::Record qw(qsearch); use FS::svc_acct; -my $user = shift or die &usage; -adminsuidsetup $user; - -$conf = new FS::Conf; - -my @shellmachines = $conf->config('shellmachines') - if $conf->exists('shellmachines'); - -my @bsdshellmachines = $conf->config('bsdshellmachines') - if $conf->exists('bsdshellmachines'); - -my @nismachines = $conf->config('nismachines') - if $conf->exists('nismachines'); - -my @erpcdmachines = $conf->config('erpcdmachines') - if $conf->exists('erpcdmachines'); - -my @radiusmachines = $conf->config('radiusmachines') - if $conf->exists('radiusmachines'); - -my $icradiusmachines = $conf->exists('icradiusmachines'); -my @icradiusmachines = $conf->config('icradiusmachines') if $icradiusmachines; -my $icradius_mysqldest = - $conf->config('icradius_mysqldest') || "/usr/local/var/" - if $icradiusmachines; -my $icradius_mysqlsource = - $conf->config('icradius_mysqlsource') || "/usr/local/var/freeside" - if $icradiusmachines; -my $icradius_dbh; -if ( $icradiusmachines && $conf->exists('icradius_secrets') ) { - $icradius_dbh = DBI->connect($conf->config('icradius_secrets')) - or die $DBI::errstr;; -} else { - $icradius_dbh = dbh; -} - -my $textradiusprepend = $conf->config('textradiusprepend'); - -my(@saltset)= ( 'a'..'z' , 'A'..'Z' , '0'..'9' , '.' , '/' ); -require 5.004; #srand(time|$$); - -my $spooldir = "/usr/local/etc/freeside/export.". datasrc; -my $spoollock = "/usr/local/etc/freeside/svc_acct.export.lock.". datasrc; - -open(EXPORT,"+>>$spoollock") or die "Can't open $spoollock: $!"; -select(EXPORT); $|=1; select(STDOUT); -unless ( flock(EXPORT,LOCK_EX|LOCK_NB) ) { - seek(EXPORT,0,0); - my($pid)=; - chop($pid); - #no reason to start loct of blocking processes - die "Is another export process running under pid $pid?\n"; -} -seek(EXPORT,0,0); -print EXPORT $$,"\n"; - -my(@svc_acct)=qsearch('svc_acct',{}); - -( open(MASTER,">$spooldir/master.passwd") - and flock(MASTER,LOCK_EX|LOCK_NB) -) or die "Can't open $spooldir/master.passwd: $!"; -( open(PASSWD,">$spooldir/passwd") - and flock(PASSWD,LOCK_EX|LOCK_NB) -) or die "Can't open $spooldir/passwd: $!"; -( open(SHADOW,">$spooldir/shadow") - and flock(SHADOW,LOCK_EX|LOCK_NB) -) or die "Can't open $spooldir/shadow: $!"; -( open(ACP_PASSWD,">$spooldir/acp_passwd") - and flock (ACP_PASSWD,LOCK_EX|LOCK_NB) -) or die "Can't open $spooldir/acp_passwd: $!"; -( open (ACP_DIALUP,">$spooldir/acp_dialup") - and flock(ACP_DIALUP,LOCK_EX|LOCK_NB) -) or die "Can't open $spooldir/acp_dialup: $!"; -( open (USERS,">$spooldir/users") - and flock(USERS,LOCK_EX|LOCK_NB) -) or die "Can't open $spooldir/users: $!"; - -chmod 0644, "$spooldir/passwd", - "$spooldir/acp_dialup", -; -chmod 0600, "$spooldir/master.passwd", - "$spooldir/acp_passwd", - "$spooldir/shadow", - "$spooldir/users", -; - -if ( $icradiusmachines ) { - my $sth = $icradius_dbh->prepare("DELETE FROM radcheck"); - $sth->execute or die "Can't reset radcheck table: ". $sth->errstr; - my $sth2 = $icradius_dbh->prepare("DELETE FROM radreply"); - $sth2->execute or die "Can't reset radreply table: ". $sth2->errstr; -} - -setpriority(0,0,10); - -my($svc_acct); -foreach $svc_acct (@svc_acct) { - - my($password)=$svc_acct->getfield('_password'); - my($cpassword,$rpassword); - if ( ( length($password) <= 8 ) - && ( $password ne '*' ) - && ( $password ne '' ) - ) { - $cpassword=crypt($password, - $saltset[int(rand(64))].$saltset[int(rand(64))] - ); - $rpassword=$password; - } else { - $cpassword=$password; - $rpassword='UNIX'; - } - - if ( $svc_acct->uid =~ /^(\d+)$/ ) { - - die "Non-root user ". $svc_acct->username. " has 0 UID!" - if $svc_acct->uid == 0 && $svc_acct->username ne 'root'; - - ### - # FORMAT OF FreeBSD MASTER PASSWD FILE HERE - print MASTER join(":", - $svc_acct->username, # User name - $cpassword, # Encrypted password - $svc_acct->uid, # User ID - $svc_acct->gid, # Group ID - "", # Login Class - "0", # Password Change Time - "0", # Password Expiration Time - $svc_acct->finger, # Users name - $svc_acct->dir, # Users home directory - $svc_acct->shell, # shell - ), "\n" ; - - ### - # FORMAT OF THE PASSWD FILE HERE - print PASSWD join(":", - $svc_acct->username, - 'x', # "##". $svc_acct->$username, - $svc_acct->uid, - $svc_acct->gid, - $svc_acct->finger, - $svc_acct->dir, - $svc_acct->shell, - ), "\n"; - - ### - # FORMAT OF THE SHADOW FILE HERE - print SHADOW join(":", - $svc_acct->username, - $cpassword, - '', - '', - '', - '', - '', - '', - '', - ), "\n"; - - } - - if ( $svc_acct->slipip ne '' ) { - - ### - # FORMAT OF THE ACP_* FILES HERE - print ACP_PASSWD join(":", - $svc_acct->username, - $cpassword, - "0", - "0", - "", - "", - "", - ), "\n"; - - my($ip)=$svc_acct->slipip; - - unless ( $ip eq '0.0.0.0' || $svc_acct->slipip eq '0e0' ) { - print ACP_DIALUP $svc_acct->username, "\t*\t", $svc_acct->slipip, "\n"; - } - - my %radreply = $svc_acct->radius_reply; - my %radcheck = $svc_acct->radius_check; - - my $radcheck = join ", ", map { qq($_ = "$radcheck{$_}") } keys %radcheck; - $radcheck .= ", " if $radcheck; - - ### - # FORMAT OF THE USERS FILE HERE - print USERS - $svc_acct->username, - qq(\t${textradiusprepend}), - $radcheck, - qq(Password = "$rpassword"\n\t), - join ",\n\t", map { qq($_ = "$radreply{$_}") } keys %radreply; - - if ( $ip && $ip ne '0e0' ) { - #print USERS qq(,\n\tFramed-Address = "$ip"\n\n); - print USERS qq(,\n\tFramed-IP-Address = "$ip"\n\n); - } else { - print USERS qq(\n\n); - } - - ### - # ICRADIUS export - if ( $icradiusmachines ) { - - my $sth = $icradius_dbh->prepare( - "INSERT INTO radcheck ( id, UserName, Attribute, Value ) VALUES ( ". - join(", ", map { $icradius_dbh->quote( $_ ) } ( - '', - $svc_acct->username, - "Password", - $svc_acct->_password, - ) ). " )" - ); - $sth->execute or die "Can't insert into radcheck table: ". $sth->errstr; - - foreach my $attribute ( keys %radcheck ) { - my $sth = $icradius_dbh->prepare( - "INSERT INTO radcheck ( id, UserName, Attribute, Value ) VALUES ( ". - join(", ", map { $icradius_dbh->quote( $_ ) } ( - '', - $svc_acct->username, - $attribute, - $radcheck{$attribute}, - ) ). " )" - ); - $sth->execute or die "Can't insert into radcheck table: ". $sth->errstr; - } - - foreach my $attribute ( keys %radreply ) { - my $sth = $icradius_dbh->prepare( - "INSERT INTO radreply (id, UserName, Attribute, Value) VALUES ( ". - join(", ", map { $icradius_dbh->quote( $_ ) } ( - '', - $svc_acct->username, - $attribute, - $radreply{$attribute}, - ) ). " )" - ); - $sth->execute or die "Can't insert into radreply table: ". $sth->errstr; - } - - } - - } - -} - -flock(MASTER,LOCK_UN); -flock(PASSWD,LOCK_UN); -flock(SHADOW,LOCK_UN); -flock(ACP_DIALUP,LOCK_UN); -flock(ACP_PASSWD,LOCK_UN); -flock(USERS,LOCK_UN); - -close MASTER; -close PASSWD; -close SHADOW; -close ACP_DIALUP; -close ACP_PASSWD; -close USERS; - -### -# export stuff -# - -my($shellmachine); -foreach $shellmachine (@shellmachines) { - scp("$spooldir/passwd","root\@$shellmachine:/etc/passwd.new") - == 0 or die "scp error: $!"; - scp("$spooldir/shadow","root\@$shellmachine:/etc/shadow.new") - == 0 or die "scp error: $!"; - ssh("root\@$shellmachine", - "( ". - "mv /etc/passwd.new /etc/passwd; ". - "mv /etc/shadow.new /etc/shadow; ". - " )" - ) - == 0 or die "ssh error: $!"; -} - -my($bsdshellmachine); -foreach $bsdshellmachine (@bsdshellmachines) { - scp("$spooldir/passwd","root\@$bsdshellmachine:/etc/passwd.new") - == 0 or die "scp error: $!"; - scp("$spooldir/master.passwd","root\@$bsdshellmachine:/etc/master.passwd.new") - == 0 or die "scp error: $!"; - ssh("root\@$bsdshellmachine", - "( ". - "mv /etc/passwd.new /etc/passwd; ". - "mv /etc/master.passwd.new /etc/master.passwd; ". - " )" +my @fields = ( + { 'header' => 'pkgnum', + 'callback' => sub { shift->cust_svc->pkgnum; }, + }, + { 'header' => 'svcpart', + 'callback' => sub { shift->cust_svc->svcpart; }, + }, + { 'header' => 'Service', + 'callback' => sub { shift->cust_svc->part_svc->svc; }, + }, + qw( + username + _password + slipip ) - == 0 or die "ssh error: $!"; -} - -my($nismachine); -foreach $nismachine (@nismachines) { - scp("$spooldir/passwd","root\@$nismachine:/etc/global/passwd") - == 0 or die "scp error: $!"; - scp("$spooldir/shadow","root\@$nismachine:/etc/global/shadow") - == 0 or die "scp error: $!"; - ssh("root\@$nismachine", - "( ". - "cd /var/yp; make; ". - " )" - ) - == 0 or die "ssh error: $!"; -} +); -my($erpcdmachine); -foreach $erpcdmachine (@erpcdmachines) { - scp("$spooldir/acp_passwd","root\@$erpcdmachine:/usr/annex/acp_passwd") - == 0 or die "scp error: $!"; - scp("$spooldir/acp_dialup","root\@$erpcdmachine:/usr/annex/acp_dialup") - == 0 or die "scp error: $!"; - ssh("root\@$erpcdmachine", - "( ". - "kill -USR1 \`cat /usr/annex/erpcd.pid\'". - " )" - ) - == 0 or die "ssh error: $!"; -} +my $user = shift or die &usage; +adminsuidsetup $user; -my($radiusmachine); -foreach $radiusmachine (@radiusmachines) { - scp("$spooldir/users","root\@$radiusmachine:/etc/raddb/users") - == 0 or die "scp error: $!"; - ssh("root\@$radiusmachine", - "( ". - "builddbm". - " )" - ) - == 0 or die "ssh error: $!"; -} +my $agentnum = shift or die &usage; -foreach my $icradiusmachine ( @icradiusmachines ) { - my( $machine, $db, $user, $pass ) = split(/\s+/, $icradiusmachine); - chdir $icradius_mysqlsource or die "Can't cd $icradius_mysqlsource: $!"; - open(WRITER,"|ssh root\@$machine mysql -v --user=$user -p $db"); - my $oldfh = select WRITER; $|=1; select $oldfh; - print WRITER "$pass\n"; - sleep 2; - print WRITER "LOCK TABLES radcheck WRITE, radreply WRITE;\n"; - foreach my $file ( glob("radcheck.*") ) { - scp($file,"root\@$machine:$icradius_mysqldest/$db/$file"); - } - foreach my $file ( glob("radreply.*") ) { - scp($file,"root\@$machine:$icradius_mysqldest/$db/$file"); - } - close WRITER; -} +my $csv = new Text::CSV_XS; -unlink $spoollock; -flock(EXPORT,LOCK_UN); -close EXPORT; +$csv->combine( map { ref($_) ? $_->{'header'} : $_ } @fields ) or die; +print $csv->string."\n"; -# +my @svc_acct = qsearch({ + 'table' => 'svc_acct', + 'addl_from' => 'LEFT JOIN cust_svc USING (svcnum) + LEFT JOIN cust_pkg USING (pkgnum) + LEFT JOIN cust_main USING ( custnum )', + 'hashref' => {}, + 'extra_sql' => "WHERE cust_main.agentnum = $agentnum", +}); -sub usage { - die "Usage:\n\n svc_acct.export user\n"; +foreach my $svc_acct ( @svc_acct ) { + $csv->combine( map { ref($_) ? &{$_->{'callback'}}($svc_acct) + : $svc_acct->$_() + } + @fields + ) or die; + print $csv->string."\n"; } +1;