diff options
Diffstat (limited to 'bin')
-rwxr-xr-x | bin/apache.export | 4 | ||||
-rwxr-xr-x | bin/bind.export | 16 | ||||
-rwxr-xr-x | bin/bind.import | 60 | ||||
-rwxr-xr-x | bin/fs-setup | 1038 | ||||
-rwxr-xr-x | bin/masonize | 32 | ||||
-rwxr-xr-x | bin/passwd.import | 3 | ||||
-rwxr-xr-x | bin/postfix.export | 122 | ||||
-rwxr-xr-x | bin/postfix_courierimap.import | 137 | ||||
-rw-r--r-- | bin/sendmail.import | 176 | ||||
-rwxr-xr-x | bin/shadow.reimport | 125 | ||||
-rw-r--r-- | bin/sqlradius.import | 152 | ||||
-rwxr-xr-x | bin/sqlradius.reimport | 156 |
12 files changed, 949 insertions, 1072 deletions
diff --git a/bin/apache.export b/bin/apache.export index f0a6beefc..47863a9d5 100755 --- a/bin/apache.export +++ b/bin/apache.export @@ -51,7 +51,9 @@ foreach my $export ( @exports ) { } ) or die "rsync to $machine failed: ". join(" / ", $rsync->err); # warn $rsync->out; - ssh("root\@$machine", 'apachectl graceful'); + my $restart = $export->option('restart') || 'apachectl graceful'; + + ssh("root\@$machine", $restart); } diff --git a/bin/bind.export b/bin/bind.export index 055782a20..d0b93797e 100755 --- a/bin/bind.export +++ b/bin/bind.export @@ -30,6 +30,11 @@ foreach my $export ( @exports ) { my $machine = $export->machine; my $prefix = "$spooldir/$machine"; + my $bind_rel = $export->option('bind_release'); + my $ndc_cmd = $export->option('reload') + || ( ($bind_rel eq 'BIND9') ? 'rndc' : 'ndc' ); + my $minttl = $export->option('bind9_minttl'); + #prevent old domain files from piling up #rmtree "$prefix" or die "can't rmtree $prefix.db: $!"; @@ -79,6 +84,10 @@ END open (DB_MASTER,">$prefix/db.$domain") or die "can't open $prefix/db.$domain: $!"; + if ($bind_rel eq 'BIND9') { + print DB_MASTER "\$TTL $minttl\n\$ORIGIN $domain.\n"; + } + my @domain_records = qsearch('domain_record', { 'svcnum' => $svc_domain->svcnum } ); foreach my $domain_record ( @@ -114,7 +123,7 @@ END } ) or die "rsync to $machine failed: ". join(" / ", $rsync->err); # warn $rsync->out; - ssh("root\@$machine", 'ndc reload'); + ssh("root\@$machine", "$ndc_cmd reload"); } @@ -125,6 +134,9 @@ foreach my $sexport ( @sexports ) { #false laziness with above my $machine = $sexport->machine; my $prefix = "$spooldir/$machine"; + my $bind_rel = $sexport->option('bind_release'); + my $ndc_cmd = ($bind_rel eq 'BIND9') ? 'rndc' : 'ndc'; + #prevent old domain files from piling up #rmtree "$prefix" or die "can't rmtree $prefix.db: $!"; @@ -166,7 +178,7 @@ END } ) or die "rsync to $machine failed: ". join(" / ", $rsync->err); # warn $rsync->out; - ssh("root\@$machine", 'ndc reload'); + ssh("root\@$machine", "$ndc_cmd reload"); } close NAMED_CONF; diff --git a/bin/bind.import b/bin/bind.import index 57eca2b63..41313fba6 100755 --- a/bin/bind.import +++ b/bin/bind.import @@ -1,11 +1,16 @@ #!/usr/bin/perl -w # -# $Id: bind.import,v 1.3 2002-07-15 01:44:23 ivan Exp $ - -#need to manually put header in /usr/local/etc/freeside/export.<datasrc./bind/<machine>/named.conf.HEADER +# -s: import slave zones as master. useful if you need to recreate your +# primary nameserver from a secondary +# -c chroot_dir: import data from chrooted bind (corrects the path for +# downloading zone files +# +# need to manually put header in +# /usr/local/etc/freeside/export.<datasrc./bind/<machine>/named.conf.HEADER use strict; use vars qw( %d_part_svc ); +use Getopt::Std; use Term::Query qw(query); #use BIND::Conf_Parser; #use DNS::ZoneParse 0.81; @@ -20,6 +25,9 @@ use FS::domain_record; #use FS::svc_acct; #use FS::part_svc; +use vars qw($opt_s $opt_c); +getopts("sc:"); + my $user = shift or die &usage; adminsuidsetup $user; @@ -79,7 +87,7 @@ print "\nBIND import completed.\n"; ## sub usage { - die "Usage:\n\n svc_domain.import user\n"; + die "Usage:\n\n bind.import user\n"; } ######## @@ -99,18 +107,28 @@ BEGIN { sub handle_zone { my($self, $name, $class, $type, $options) = @_; return unless $class eq 'in'; - return if grep { $name eq $_ } - ( qw( . localhost 127.in-addr.arpa 0.in-addr.arpa 255.in-addr.arpa ) ); - - my $domain = new FS::svc_domain( { - svcpart => $main::domain_svcpart, - domain => $name, - action => 'N', - } ); - my $error = $domain->insert; - die $error if $error; + return if grep { $name eq $_ } (qw( + . localhost 127.in-addr.arpa 0.in-addr.arpa 255.in-addr.arpa + 0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa + 0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.int + )); + + use FS::Record qw(qsearchs); + use FS::svc_domain; + + my $domain = + qsearchs('svc_domain', { 'domain' => $name } ) + || new FS::svc_domain( { + svcpart => $main::domain_svcpart, + domain => $name, + action => 'N', + } ); + unless ( $domain->svcnum ) { + my $error = $domain->insert; + die $error if $error; + } - if ( $type eq 'slave' ) { + if ( $type eq 'slave' && !$main::opt_s ) { #use Data::Dumper; #print Dumper($options); @@ -128,7 +146,7 @@ BEGIN { die $error if $error; } - } elsif ( $type eq 'master' ) { + } elsif ( $type eq 'master' || ( $type eq 'slave' && $main::opt_s ) ) { my $file = $options->{file}; @@ -136,14 +154,16 @@ BEGIN { my $basefile = basename($file); my $sourcefile = $file; $sourcefile = "$named_dir/$sourcefile" unless $file =~ /^\//; + $sourcefile = "$main::opt_c/$sourcefile" if $main::opt_c; + use Net::SCP qw(iscp scp); scp("root\@$main::named_machine:$sourcefile", - "$main::prefix/$basefile.import"); + "$main::prefix/$basefile.import"); - use DNS::ZoneParse 0.81; + use DNS::ZoneParse 0.84; my $zone = DNS::ZoneParse->new("$main::prefix/$basefile.import"); - my $dump = $zone->Dump; + my $dump = $zone->dump; #use Data::Dumper; #print "$name: ". Dumper($dump); @@ -183,6 +203,8 @@ BEGIN { } } + #} else { + # die "unrecognized type $type\n"; } } diff --git a/bin/fs-setup b/bin/fs-setup deleted file mode 100755 index 973523cf2..000000000 --- a/bin/fs-setup +++ /dev/null @@ -1,1038 +0,0 @@ -#!/usr/bin/perl -Tw -# -# $Id: fs-setup,v 1.96.4.7 2003-06-14 02:02:25 ivan Exp $ - -#to delay loading dbdef until we're ready -BEGIN { $FS::Record::setup_hack = 1; } - -use strict; -use DBI; -use DBIx::DBSchema 0.20; -use DBIx::DBSchema::Table; -use DBIx::DBSchema::Column; -use DBIx::DBSchema::ColGroup::Unique; -use DBIx::DBSchema::ColGroup::Index; -use FS::UID qw(adminsuidsetup datasrc checkeuid getsecrets); -use FS::Record; -use FS::cust_main_county; -use FS::raddb; -use FS::part_bill_event; - -die "Not running uid freeside!" unless checkeuid(); - -my %attrib2db = - map { lc($FS::raddb::attrib{$_}) => $_ } keys %FS::raddb::attrib; - -my $user = shift or die &usage; -getsecrets($user); - -#needs to match FS::Record -my($dbdef_file) = "/usr/local/etc/freeside/dbdef.". datasrc; - -### - -#print "\nEnter the maximum username length: "; -#my($username_len)=&getvalue; -my $username_len = 32; #usernamemax config file - -print "\n\n", <<END, ":"; -Freeside tracks the RADIUS User-Name, check attribute Password and -reply attribute Framed-IP-Address for each user. You can specify additional -check and reply attributes (or you can add them later with the -fs-radius-add-check and fs-radius-add-reply programs). - -First enter any additional RADIUS check attributes you need to track for each -user, separated by whitespace. -END -my @check_attributes = map { $attrib2db{lc($_)} or die "unknown attribute $_"; } - split(" ",&getvalue); - -print "\n\n", <<END, ":"; -Now enter any additional reply attributes you need to track for each user, -separated by whitespace. -END -my @attributes = map { $attrib2db{lc($_)} or die "unknown attribute $_"; } - split(" ",&getvalue); - -print "\n\n", <<END, ":"; -Do you wish to enable the tracking of a second, separate shipping/service -address? -END -my $ship = &_yesno; - -sub getvalue { - my($x)=scalar(<STDIN>); - chop $x; - $x; -} - -sub _yesno { - print " [y/N]:"; - my $x = scalar(<STDIN>); - $x =~ /^y/i; -} - -### - -my($char_d) = 80; #default maxlength for text fields - -#my(@date_type) = ( 'timestamp', '', '' ); -my(@date_type) = ( 'int', 'NULL', '' ); -my(@perl_type) = ( 'text', 'NULL', '' ); -my @money_type = ( 'decimal', '', '10,2' ); - -### -# create a dbdef object from the old data structure -### - -my(%tables)=&tables_hash_hack; - -#turn it into objects -my($dbdef) = new DBIx::DBSchema ( map { - my(@columns); - while (@{$tables{$_}{'columns'}}) { - my($name,$type,$null,$length)=splice @{$tables{$_}{'columns'}}, 0, 4; - push @columns, new DBIx::DBSchema::Column ( $name,$type,$null,$length ); - } - DBIx::DBSchema::Table->new( - $_, - $tables{$_}{'primary_key'}, - DBIx::DBSchema::ColGroup::Unique->new($tables{$_}{'unique'}), - DBIx::DBSchema::ColGroup::Index->new($tables{$_}{'index'}), - @columns, - ); -} (keys %tables) ); - -my $cust_main = $dbdef->table('cust_main'); -unless ($ship) { #remove ship_ from cust_main - $cust_main->delcolumn($_) foreach ( grep /^ship_/, $cust_main->columns ); -} else { #add indices - push @{$cust_main->index->lol_ref}, - map { [ "ship_$_" ] } qw( last company daytime night fax ); -} - -#add radius attributes to svc_acct - -my($svc_acct)=$dbdef->table('svc_acct'); - -my($attribute); -foreach $attribute (@attributes) { - $svc_acct->addcolumn ( new DBIx::DBSchema::Column ( - 'radius_'. $attribute, - 'varchar', - 'NULL', - $char_d, - )); -} - -foreach $attribute (@check_attributes) { - $svc_acct->addcolumn( new DBIx::DBSchema::Column ( - 'rc_'. $attribute, - 'varchar', - 'NULL', - $char_d, - )); -} - -##make part_svc table (but now as object) -# -#my($part_svc)=$dbdef->table('part_svc'); -# -##because of svc_acct_pop -##foreach (grep /^svc_/, $dbdef->tables) { -##foreach (qw(svc_acct svc_acct_sm svc_charge svc_domain svc_wo)) { -#foreach (qw(svc_acct svc_domain svc_forward svc_www)) { -# my($table)=$dbdef->table($_); -# my($col); -# foreach $col ( $table->columns ) { -# next if $col =~ /^svcnum$/; -# $part_svc->addcolumn( new DBIx::DBSchema::Column ( -# $table->name. '__' . $table->column($col)->name, -# 'varchar', #$table->column($col)->type, -# 'NULL', -# $char_d, #$table->column($col)->length, -# )); -# $part_svc->addcolumn ( new DBIx::DBSchema::Column ( -# $table->name. '__'. $table->column($col)->name . "_flag", -# 'char', -# 'NULL', -# 1, -# )); -# } -#} - -#create history tables (false laziness w/create-history-tables) -foreach my $table ( grep { ! /^h_/ } $dbdef->tables ) { - my $tableobj = $dbdef->table($table) - or die "unknown table $table"; - - die "unique->lol_ref undefined for $table" - unless defined $tableobj->unique->lol_ref; - die "index->lol_ref undefined for $table" - unless defined $tableobj->index->lol_ref; - - my $h_tableobj = DBIx::DBSchema::Table->new( { - name => "h_$table", - primary_key => 'historynum', - unique => DBIx::DBSchema::ColGroup::Unique->new( [] ), - 'index' => DBIx::DBSchema::ColGroup::Index->new( [ - @{$tableobj->unique->lol_ref}, - @{$tableobj->index->lol_ref} - ] ), - columns => [ - DBIx::DBSchema::Column->new( { - 'name' => 'historynum', - 'type' => 'serial', - 'null' => 'NOT NULL', - 'length' => '', - 'default' => '', - 'local' => '', - } ), - DBIx::DBSchema::Column->new( { - 'name' => 'history_date', - 'type' => 'int', - 'null' => 'NULL', - 'length' => '', - 'default' => '', - 'local' => '', - } ), - DBIx::DBSchema::Column->new( { - 'name' => 'history_user', - 'type' => 'varchar', - 'null' => 'NOT NULL', - 'length' => '80', - 'default' => '', - 'local' => '', - } ), - DBIx::DBSchema::Column->new( { - 'name' => 'history_action', - 'type' => 'varchar', - 'null' => 'NOT NULL', - 'length' => '80', - 'default' => '', - 'local' => '', - } ), - map { $tableobj->column($_) } $tableobj->columns - ], - } ); - $dbdef->addtable($h_tableobj); -} - -#important -$dbdef->save($dbdef_file); -&FS::Record::reload_dbdef($dbdef_file); - -### -# create 'em -### - -my($dbh)=adminsuidsetup $user; - -#create tables -$|=1; - -foreach my $statement ( $dbdef->sql($dbh) ) { - $dbh->do( $statement ) - or die "CREATE error: ". $dbh->errstr. "\ndoing statement: $statement"; -} - -#not really sample data (and shouldn't default to US) - -#cust_main_county - -#USPS state codes -foreach ( qw( -AL AK AS AZ AR CA CO CT DC DE FM FL GA GU HI ID IL IN IA KS KY LA -ME MH MD MA MI MN MS MO MT NC ND NE NH NJ NM NV NY MP OH OK OR PA PW PR RI -SC SD TN TX UT VT VI VA WA WV WI WY AE AA AP -) ) { - my($cust_main_county)=new FS::cust_main_county({ - 'state' => $_, - 'tax' => 0, - 'country' => 'US', - }); - my($error); - $error=$cust_main_county->insert; - die $error if $error; -} - -#AU "offical" state codes ala mark.williamson@ebbs.com.au (Mark Williamson) -foreach ( qw( -VIC NSW NT QLD TAS ACT WA SA -) ) { - my($cust_main_county)=new FS::cust_main_county({ - 'state' => $_, - 'tax' => 0, - 'country' => 'AU', - }); - my($error); - $error=$cust_main_county->insert; - die $error if $error; -} - -#ISO 2-letter country codes (same as country TLDs) except US and AU -foreach ( qw( -AF AL DZ AS AD AO AI AQ AG AR AM AW AT AZ BS BH BD BB BY BE BZ BJ BM BT BO -BA BW BV BR IO BN BG BF BI KH CM CA CV KY CF TD CL CN CX CC CO KM CG CK CR CI -HR CU CY CZ DK DJ DM DO TP EC EG SV GQ ER EE ET FK FO FJ FI FR FX GF PF TF GA -GM GE DE GH GI GR GL GD GP GU GT GN GW GY HT HM HN HK HU IS IN ID IR IQ IE IL -IT JM JP JO KZ KE KI KP KR KW KG LA LV LB LS LR LY LI LT LU MO MK MG MW MY MV -ML MT MH MQ MR MU YT MX FM MD MC MN MS MA MZ MM NA NR NP NL AN NC NZ NI NE NG -NU NF MP NO OM PK PW PA PG PY PE PH PN PL PT PR QA RE RO RU RW KN LC VC WS SM -ST SA SN SC SL SG SK SI SB SO ZA GS ES LK SH PM SD SR SJ SZ SE CH SY TW TJ TZ -TH TG TK TO TT TN TR TM TC TV UG UA AE GB UM UY UZ VU VA VE VN VG VI WF EH -YE YU ZR ZM ZW -) ) { - my($cust_main_county)=new FS::cust_main_county({ - 'tax' => 0, - 'country' => $_, - }); - my($error); - $error=$cust_main_county->insert; - die $error if $error; -} - -#billing events -foreach my $aref ( - [ 'COMP', 'Comp invoice', '$cust_bill->comp();', 30, 'comp' ], - [ 'CARD', 'Batch card', '$cust_bill->batch_card();', 40, 'batch-card' ], - [ 'BILL', 'Send invoice', '$cust_bill->send();', 50, 'send' ], -) { - - my $part_bill_event = new FS::part_bill_event({ - 'payby' => $aref->[0], - 'event' => $aref->[1], - 'eventcode' => $aref->[2], - 'seconds' => 0, - 'weight' => $aref->[3], - 'plan' => $aref->[4], - }); - my($error); - $error=$part_bill_event->insert; - die $error if $error; - -} - -$dbh->commit or die $dbh->errstr; -$dbh->disconnect or die $dbh->errstr; - -print "Freeside database initialized sucessfully\n"; - -sub usage { - die "Usage:\n fs-setup user\n"; -} - -### -# Now it becomes an object. much better. -### -sub tables_hash_hack { - - #note that s/(date|change)/_$1/; to avoid keyword conflict. - #put a kludge in FS::Record to catch this or? (pry need some date-handling - #stuff anyway also) - - my(%tables)=( #yech.} - - 'agent' => { - 'columns' => [ - 'agentnum', 'int', '', '', - 'agent', 'varchar', '', $char_d, - 'typenum', 'int', '', '', - 'freq', 'int', 'NULL', '', - 'prog', @perl_type, - ], - 'primary_key' => 'agentnum', - 'unique' => [], - 'index' => [ ['typenum'] ], - }, - - 'agent_type' => { - 'columns' => [ - 'typenum', 'int', '', '', - 'atype', 'varchar', '', $char_d, - ], - 'primary_key' => 'typenum', - 'unique' => [], - 'index' => [], - }, - - 'type_pkgs' => { - 'columns' => [ - 'typenum', 'int', '', '', - 'pkgpart', 'int', '', '', - ], - 'primary_key' => '', - 'unique' => [ ['typenum', 'pkgpart'] ], - 'index' => [ ['typenum'] ], - }, - - 'cust_bill' => { - 'columns' => [ - 'invnum', 'int', '', '', - 'custnum', 'int', '', '', - '_date', @date_type, - 'charged', @money_type, - 'printed', 'int', '', '', - 'closed', 'char', 'NULL', 1, - ], - 'primary_key' => 'invnum', - 'unique' => [], - 'index' => [ ['custnum'], ['_date'] ], - }, - - 'cust_bill_event' => { - 'columns' => [ - 'eventnum', 'int', '', '', - 'invnum', 'int', '', '', - 'eventpart', 'int', '', '', - '_date', @date_type, - 'status', 'varchar', '', $char_d, - 'statustext', 'text', 'NULL', '', - ], - 'primary_key' => 'eventnum', - #no... there are retries now #'unique' => [ [ 'eventpart', 'invnum' ] ], - 'unique' => [], - 'index' => [ ['invnum'], ['status'] ], - }, - - 'part_bill_event' => { - 'columns' => [ - 'eventpart', 'int', '', '', - 'payby', 'char', '', 4, - 'event', 'varchar', '', $char_d, - 'eventcode', @perl_type, - 'seconds', 'int', 'NULL', '', - 'weight', 'int', '', '', - 'plan', 'varchar', 'NULL', $char_d, - 'plandata', 'text', 'NULL', '', - 'disabled', 'char', 'NULL', 1, - ], - 'primary_key' => 'eventpart', - 'unique' => [], - 'index' => [ ['payby'] ], - }, - - 'cust_bill_pkg' => { - 'columns' => [ - 'pkgnum', 'int', '', '', - 'invnum', 'int', '', '', - 'setup', @money_type, - 'recur', @money_type, - 'sdate', @date_type, - 'edate', @date_type, - ], - 'primary_key' => '', - 'unique' => [ ['pkgnum', 'invnum'] ], - 'index' => [ ['invnum'] ], - }, - - 'cust_credit' => { - 'columns' => [ - 'crednum', 'int', '', '', - 'custnum', 'int', '', '', - '_date', @date_type, - 'amount', @money_type, - 'otaker', 'varchar', '', 8, - 'reason', 'text', 'NULL', '', - 'closed', 'char', 'NULL', 1, - ], - 'primary_key' => 'crednum', - 'unique' => [], - 'index' => [ ['custnum'] ], - }, - - 'cust_credit_bill' => { - 'columns' => [ - 'creditbillnum', 'int', '', '', - 'crednum', 'int', '', '', - 'invnum', 'int', '', '', - '_date', @date_type, - 'amount', @money_type, - ], - 'primary_key' => 'creditbillnum', - 'unique' => [], - 'index' => [ ['crednum'], ['invnum'] ], - }, - - 'cust_main' => { - 'columns' => [ - 'custnum', 'int', '', '', - 'agentnum', 'int', '', '', -# 'titlenum', 'int', 'NULL', '', - 'last', 'varchar', '', $char_d, -# 'middle', 'varchar', 'NULL', $char_d, - 'first', 'varchar', '', $char_d, - 'ss', 'char', 'NULL', 11, - 'company', 'varchar', 'NULL', $char_d, - 'address1', 'varchar', '', $char_d, - 'address2', 'varchar', 'NULL', $char_d, - 'city', 'varchar', '', $char_d, - 'county', 'varchar', 'NULL', $char_d, - 'state', 'varchar', 'NULL', $char_d, - 'zip', 'varchar', '', 10, - 'country', 'char', '', 2, - 'daytime', 'varchar', 'NULL', 20, - 'night', 'varchar', 'NULL', 20, - 'fax', 'varchar', 'NULL', 12, - 'ship_last', 'varchar', 'NULL', $char_d, -# 'ship_middle', 'varchar', 'NULL', $char_d, - 'ship_first', 'varchar', 'NULL', $char_d, - 'ship_company', 'varchar', 'NULL', $char_d, - 'ship_address1', 'varchar', 'NULL', $char_d, - 'ship_address2', 'varchar', 'NULL', $char_d, - 'ship_city', 'varchar', 'NULL', $char_d, - 'ship_county', 'varchar', 'NULL', $char_d, - 'ship_state', 'varchar', 'NULL', $char_d, - 'ship_zip', 'varchar', 'NULL', 10, - 'ship_country', 'char', 'NULL', 2, - 'ship_daytime', 'varchar', 'NULL', 20, - 'ship_night', 'varchar', 'NULL', 20, - 'ship_fax', 'varchar', 'NULL', 12, - 'payby', 'char', '', 4, - 'payinfo', 'varchar', 'NULL', $char_d, - #'paydate', @date_type, - 'paydate', 'varchar', 'NULL', 10, - 'payname', 'varchar', 'NULL', $char_d, - 'tax', 'char', 'NULL', 1, - 'otaker', 'varchar', '', 8, - 'refnum', 'int', '', '', - 'referral_custnum', 'int', 'NULL', '', - 'comments', 'text', 'NULL', '', - ], - 'primary_key' => 'custnum', - 'unique' => [], - #'index' => [ ['last'], ['company'] ], - 'index' => [ ['last'], [ 'company' ], [ 'referral_custnum' ], - [ 'daytime' ], [ 'night' ], [ 'fax' ], - ], - }, - - 'cust_main_invoice' => { - 'columns' => [ - 'destnum', 'int', '', '', - 'custnum', 'int', '', '', - 'dest', 'varchar', '', $char_d, - ], - 'primary_key' => 'destnum', - 'unique' => [], - 'index' => [ ['custnum'], ], - }, - - 'cust_main_county' => { #county+state+country are checked off the - #cust_main_county for validation and to provide - # a tax rate. - 'columns' => [ - 'taxnum', 'int', '', '', - 'state', 'varchar', 'NULL', $char_d, - 'county', 'varchar', 'NULL', $char_d, - 'country', 'char', '', 2, - 'taxclass', 'varchar', 'NULL', $char_d, - 'exempt_amount', @money_type, - 'tax', 'real', '', '', #tax % - ], - 'primary_key' => 'taxnum', - 'unique' => [], - # 'unique' => [ ['taxnum'], ['state', 'county'] ], - 'index' => [], - }, - - 'cust_pay' => { - 'columns' => [ - 'paynum', 'int', '', '', - #now cust_bill_pay #'invnum', 'int', '', '', - 'custnum', 'int', '', '', - 'paid', @money_type, - '_date', @date_type, - 'payby', 'char', '', 4, # CARD/BILL/COMP, should be index into - # payment type table. - 'payinfo', 'varchar', 'NULL', $char_d, #see cust_main above - 'paybatch', 'varchar', 'NULL', $char_d, #for auditing purposes. - 'closed', 'char', 'NULL', 1, - ], - 'primary_key' => 'paynum', - 'unique' => [], - 'index' => [ [ 'custnum' ], [ 'paybatch' ] ], - }, - - 'cust_bill_pay' => { - 'columns' => [ - 'billpaynum', 'int', '', '', - 'invnum', 'int', '', '', - 'paynum', 'int', '', '', - 'amount', @money_type, - '_date', @date_type - ], - 'primary_key' => 'billpaynum', - 'unique' => [], - 'index' => [ [ 'paynum' ], [ 'invnum' ] ], - }, - - 'cust_pay_batch' => { #what's this used for again? list of customers - #in current CARD batch? (necessarily CARD?) - 'columns' => [ - 'paybatchnum', 'int', '', '', - 'invnum', 'int', '', '', - 'custnum', 'int', '', '', - 'last', 'varchar', '', $char_d, - 'first', 'varchar', '', $char_d, - 'address1', 'varchar', '', $char_d, - 'address2', 'varchar', 'NULL', $char_d, - 'city', 'varchar', '', $char_d, - 'state', 'varchar', 'NULL', $char_d, - 'zip', 'varchar', '', 10, - 'country', 'char', '', 2, -# 'trancode', 'int', '', '', - 'cardnum', 'varchar', '', 16, - #'exp', @date_type, - 'exp', 'varchar', '', 11, - 'payname', 'varchar', 'NULL', $char_d, - 'amount', @money_type, - ], - 'primary_key' => 'paybatchnum', - 'unique' => [], - 'index' => [ ['invnum'], ['custnum'] ], - }, - - 'cust_pkg' => { - 'columns' => [ - 'pkgnum', 'int', '', '', - 'custnum', 'int', '', '', - 'pkgpart', 'int', '', '', - 'otaker', 'varchar', '', 8, - 'setup', @date_type, - 'bill', @date_type, - 'susp', @date_type, - 'cancel', @date_type, - 'expire', @date_type, - 'manual_flag', 'char', 'NULL', 1, - ], - 'primary_key' => 'pkgnum', - 'unique' => [], - 'index' => [ ['custnum'] ], - }, - - 'cust_refund' => { - 'columns' => [ - 'refundnum', 'int', '', '', - #now cust_credit_refund #'crednum', 'int', '', '', - 'custnum', 'int', '', '', - '_date', @date_type, - 'refund', @money_type, - 'otaker', 'varchar', '', 8, - 'reason', 'varchar', '', $char_d, - 'payby', 'char', '', 4, # CARD/BILL/COMP, should be index - # into payment type table. - 'payinfo', 'varchar', 'NULL', $char_d, #see cust_main above - 'paybatch', 'varchar', 'NULL', $char_d, - 'closed', 'char', 'NULL', 1, - ], - 'primary_key' => 'refundnum', - 'unique' => [], - 'index' => [], - }, - - 'cust_credit_refund' => { - 'columns' => [ - 'creditrefundnum', 'int', '', '', - 'crednum', 'int', '', '', - 'refundnum', 'int', '', '', - 'amount', @money_type, - '_date', @date_type - ], - 'primary_key' => 'creditrefundnum', - 'unique' => [], - 'index' => [ [ 'crednum', 'refundnum' ] ], - }, - - - 'cust_svc' => { - 'columns' => [ - 'svcnum', 'int', '', '', - 'pkgnum', 'int', 'NULL', '', - 'svcpart', 'int', '', '', - ], - 'primary_key' => 'svcnum', - 'unique' => [], - 'index' => [ ['svcnum'], ['pkgnum'], ['svcpart'] ], - }, - - 'part_pkg' => { - 'columns' => [ - 'pkgpart', 'int', '', '', - 'pkg', 'varchar', '', $char_d, - 'comment', 'varchar', '', $char_d, - 'setup', @perl_type, - 'freq', 'int', '', '', #billing frequency (months) - 'recur', @perl_type, - 'setuptax', 'char', 'NULL', 1, - 'recurtax', 'char', 'NULL', 1, - 'plan', 'varchar', 'NULL', $char_d, - 'plandata', 'text', 'NULL', '', - 'disabled', 'char', 'NULL', 1, - 'taxclass', 'varchar', 'NULL', $char_d, - ], - 'primary_key' => 'pkgpart', - 'unique' => [], - 'index' => [ [ 'disabled' ] ], - }, - -# 'part_title' => { -# 'columns' => [ -# 'titlenum', 'int', '', '', -# 'title', 'varchar', '', $char_d, -# ], -# 'primary_key' => 'titlenum', -# 'unique' => [ [] ], -# 'index' => [ [] ], -# }, - - 'pkg_svc' => { - 'columns' => [ - 'pkgpart', 'int', '', '', - 'svcpart', 'int', '', '', - 'quantity', 'int', '', '', - ], - 'primary_key' => '', - 'unique' => [ ['pkgpart', 'svcpart'] ], - 'index' => [ ['pkgpart'] ], - }, - - 'part_referral' => { - 'columns' => [ - 'refnum', 'int', '', '', - 'referral', 'varchar', '', $char_d, - ], - 'primary_key' => 'refnum', - 'unique' => [], - 'index' => [], - }, - - 'part_svc' => { - 'columns' => [ - 'svcpart', 'int', '', '', - 'svc', 'varchar', '', $char_d, - 'svcdb', 'varchar', '', $char_d, - 'disabled', 'char', 'NULL', 1, - ], - 'primary_key' => 'svcpart', - 'unique' => [], - 'index' => [ [ 'disabled' ] ], - }, - - 'part_svc_column' => { - 'columns' => [ - 'columnnum', 'int', '', '', - 'svcpart', 'int', '', '', - 'columnname', 'varchar', '', 64, - 'columnvalue', 'varchar', 'NULL', $char_d, - 'columnflag', 'char', 'NULL', 1, - ], - 'primary_key' => 'columnnum', - 'unique' => [ [ 'svcpart', 'columnname' ] ], - 'index' => [ [ 'svcpart' ] ], - }, - - #(this should be renamed to part_pop) - 'svc_acct_pop' => { - 'columns' => [ - 'popnum', 'int', '', '', - 'city', 'varchar', '', $char_d, - 'state', 'varchar', '', $char_d, - 'ac', 'char', '', 3, - 'exch', 'char', '', 3, - 'loc', 'char', 'NULL', 4, #NULL for legacy purposes - ], - 'primary_key' => 'popnum', - 'unique' => [], - 'index' => [ [ 'state' ] ], - }, - - 'part_pop_local' => { - 'columns' => [ - 'localnum', 'int', '', '', - 'popnum', 'int', '', '', - 'city', 'varchar', 'NULL', $char_d, - 'state', 'char', 'NULL', 2, - 'npa', 'char', '', 3, - 'nxx', 'char', '', 3, - ], - 'primary_key' => 'localnum', - 'unique' => [], - 'index' => [ [ 'npa', 'nxx' ], [ 'popnum' ] ], - }, - - 'svc_acct' => { - 'columns' => [ - 'svcnum', 'int', '', '', - 'username', 'varchar', '', $username_len, #unique (& remove dup code) - '_password', 'varchar', '', 50, #13 for encryped pw's plus ' *SUSPENDED* (mp5 passwords can be 34) - 'sec_phrase', 'varchar', 'NULL', $char_d, - 'popnum', 'int', 'NULL', '', - 'uid', 'int', 'NULL', '', - 'gid', 'int', 'NULL', '', - 'finger', 'varchar', 'NULL', $char_d, - 'dir', 'varchar', 'NULL', $char_d, - 'shell', 'varchar', 'NULL', $char_d, - 'quota', 'varchar', 'NULL', $char_d, - 'slipip', 'varchar', 'NULL', 15, #four TINYINTs, bah. - 'seconds', 'int', 'NULL', '', #uhhhh - 'domsvc', 'int', '', '', - ], - 'primary_key' => 'svcnum', - #'unique' => [ [ 'username', 'domsvc' ] ], - 'unique' => [], - 'index' => [ ['username'], ['domsvc'] ], - }, - -# 'svc_acct_sm' => { -# 'columns' => [ -# 'svcnum', 'int', '', '', -# 'domsvc', 'int', '', '', -# 'domuid', 'int', '', '', -# 'domuser', 'varchar', '', $char_d, -# ], -# 'primary_key' => 'svcnum', -# 'unique' => [ [] ], -# 'index' => [ ['domsvc'], ['domuid'] ], -# }, - - #'svc_charge' => { - # 'columns' => [ - # 'svcnum', 'int', '', '', - # 'amount', @money_type, - # ], - # 'primary_key' => 'svcnum', - # 'unique' => [ [] ], - # 'index' => [ [] ], - #}, - - 'svc_domain' => { - 'columns' => [ - 'svcnum', 'int', '', '', - 'domain', 'varchar', '', $char_d, - 'catchall', 'int', 'NULL', '', - ], - 'primary_key' => 'svcnum', - 'unique' => [ ['domain'] ], - 'index' => [], - }, - - 'domain_record' => { - 'columns' => [ - 'recnum', 'int', '', '', - 'svcnum', 'int', '', '', - #'reczone', 'varchar', '', $char_d, - 'reczone', 'varchar', '', 255, - 'recaf', 'char', '', 2, - 'rectype', 'char', '', 5, - #'recdata', 'varchar', '', $char_d, - 'recdata', 'varchar', '', 255, - ], - 'primary_key' => 'recnum', - 'unique' => [], - 'index' => [ ['svcnum'] ], - }, - - 'svc_forward' => { - 'columns' => [ - 'svcnum', 'int', '', '', - 'srcsvc', 'int', '', '', - 'dstsvc', 'int', '', '', - 'dst', 'varchar', 'NULL', $char_d, - ], - 'primary_key' => 'svcnum', - 'unique' => [], - 'index' => [ ['srcsvc'], ['dstsvc'] ], - }, - - 'svc_www' => { - 'columns' => [ - 'svcnum', 'int', '', '', - 'recnum', 'int', '', '', - 'usersvc', 'int', '', '', - ], - 'primary_key' => 'svcnum', - 'unique' => [], - 'index' => [], - }, - - #'svc_wo' => { - # 'columns' => [ - # 'svcnum', 'int', '', '', - # 'svcnum', 'int', '', '', - # 'svcnum', 'int', '', '', - # 'worker', 'varchar', '', $char_d, - # '_date', @date_type, - # ], - # 'primary_key' => 'svcnum', - # 'unique' => [ [] ], - # 'index' => [ [] ], - #}, - - 'prepay_credit' => { - 'columns' => [ - 'prepaynum', 'int', '', '', - 'identifier', 'varchar', '', $char_d, - 'amount', @money_type, - 'seconds', 'int', 'NULL', '', - ], - 'primary_key' => 'prepaynum', - 'unique' => [ ['identifier'] ], - 'index' => [], - }, - - 'port' => { - 'columns' => [ - 'portnum', 'int', '', '', - 'ip', 'varchar', 'NULL', 15, - 'nasport', 'int', 'NULL', '', - 'nasnum', 'int', '', '', - ], - 'primary_key' => 'portnum', - 'unique' => [], - 'index' => [], - }, - - 'nas' => { - 'columns' => [ - 'nasnum', 'int', '', '', - 'nas', 'varchar', '', $char_d, - 'nasip', 'varchar', '', 15, - 'nasfqdn', 'varchar', '', $char_d, - 'last', 'int', '', '', - ], - 'primary_key' => 'nasnum', - 'unique' => [ [ 'nas' ], [ 'nasip' ] ], - 'index' => [ [ 'last' ] ], - }, - - 'session' => { - 'columns' => [ - 'sessionnum', 'int', '', '', - 'portnum', 'int', '', '', - 'svcnum', 'int', '', '', - 'login', @date_type, - 'logout', @date_type, - ], - 'primary_key' => 'sessionnum', - 'unique' => [], - 'index' => [ [ 'portnum' ] ], - }, - - 'queue' => { - 'columns' => [ - 'jobnum', 'int', '', '', - 'job', 'text', '', '', - '_date', 'int', '', '', - 'status', 'varchar', '', $char_d, - 'statustext', 'text', 'NULL', '', - 'svcnum', 'int', 'NULL', '', - ], - 'primary_key' => 'jobnum', - 'unique' => [], - 'index' => [ [ 'svcnum' ], [ 'status' ] ], - }, - - 'queue_arg' => { - 'columns' => [ - 'argnum', 'int', '', '', - 'jobnum', 'int', '', '', - 'arg', 'text', 'NULL', '', - ], - 'primary_key' => 'argnum', - 'unique' => [], - 'index' => [ [ 'jobnum' ] ], - }, - - 'queue_depend' => { - 'columns' => [ - 'dependnum', 'int', '', '', - 'jobnum', 'int', '', '', - 'depend_jobnum', 'int', '', '', - ], - 'primary_key' => 'dependnum', - 'unique' => [], - 'index' => [ [ 'jobnum' ], [ 'depend_jobnum' ] ], - }, - - 'export_svc' => { - 'columns' => [ - 'exportsvcnum' => 'int', '', '', - 'exportnum' => 'int', '', '', - 'svcpart' => 'int', '', '', - ], - 'primary_key' => 'exportsvcnum', - 'unique' => [ [ 'exportnum', 'svcpart' ] ], - 'index' => [ [ 'exportnum' ], [ 'svcpart' ] ], - }, - - 'part_export' => { - 'columns' => [ - 'exportnum', 'int', '', '', - #'svcpart', 'int', '', '', - 'machine', 'varchar', '', $char_d, - 'exporttype', 'varchar', '', $char_d, - 'nodomain', 'char', 'NULL', 1, - ], - 'primary_key' => 'exportnum', - 'unique' => [], - 'index' => [ [ 'machine' ], [ 'exporttype' ] ], - }, - - 'part_export_option' => { - 'columns' => [ - 'optionnum', 'int', '', '', - 'exportnum', 'int', '', '', - 'optionname', 'varchar', '', $char_d, - 'optionvalue', 'text', 'NULL', '', - ], - 'primary_key' => 'optionnum', - 'unique' => [], - 'index' => [ [ 'exportnum' ], [ 'optionname' ] ], - }, - - 'radius_usergroup' => { - 'columns' => [ - 'usergroupnum', 'int', '', '', - 'svcnum', 'int', '', '', - 'groupname', 'varchar', '', $char_d, - ], - 'primary_key' => 'usergroupnum', - 'unique' => [], - 'index' => [ [ 'svcnum' ], [ 'groupname' ] ], - }, - - 'msgcat' => { - 'columns' => [ - 'msgnum', 'int', '', '', - 'msgcode', 'varchar', '', $char_d, - 'locale', 'varchar', '', 16, - 'msg', 'text', '', '', - ], - 'primary_key' => 'msgnum', - 'unique' => [ [ 'msgcode', 'locale' ] ], - 'index' => [], - }, - - 'cust_tax_exempt' => { - 'columns' => [ - 'exemptnum', 'int', '', '', - 'custnum', 'int', '', '', - 'taxnum', 'int', '', '', - 'year', 'int', '', '', - 'month', 'int', '', '', - 'amount', @money_type, - ], - 'primary_key' => 'exemptnum', - 'unique' => [ [ 'custnum', 'taxnum', 'year', 'month' ] ], - 'index' => [], - }, - - - - ); - - %tables; - -} - diff --git a/bin/masonize b/bin/masonize index 475c9a6bf..169ba718f 100755 --- a/bin/masonize +++ b/bin/masonize @@ -1,37 +1,43 @@ #!/usr/bin/perl -foreach $file ( split(/\n/, `find . -depth -print | grep cgi\$`) ) { +foreach $file ( split(/\n/, `find . -depth -print`) ) { + next unless $file =~ /(cgi|html)$/; open(F,$file) or die "can't open $file for reading: $!"; @file = <F>; #print "$file ". scalar(@file). "\n"; close $file; - system("chmod u+w $file"); - open(W,">$file") or die "can't open $file for writing: $!"; - select W; $| = 1; select STDOUT; + $newline = ''; #avoid prepending extraneous newlines $all = join('',@file); + $w = ''; + $mode = 'html'; while ( length($all) ) { if ( $mode eq 'html' ) { if ( $all =~ /^(.+?)(<%=?.*)$/s && $1 !~ /<%/s ) { - print W $1; + $w .= $1; $all = $2; next; } elsif ( $all =~ /^<%=(.*)$/s ) { - print W '<%'; + $w .= '<%'; $all = $1; $mode = 'perlv'; #die; next; } elsif ( $all =~ /^<%(.*)$/s ) { - print W "\n"; + $w .= $newline; $newline = "\n"; $all = $1; $mode = 'perlc'; + + #avoid newline prepend fix from borking indented first <% + $w =~ s/\n\s+\z/\n/; + $w .= "\n" if $w =~ /.+\z/; + next; } elsif ( $all !~ /<%/s ) { - print W $all; + $w .= $all; last; } else { warn length($all); die; @@ -41,7 +47,7 @@ foreach $file ( split(/\n/, `find . -depth -print | grep cgi\$`) ) { } elsif ( $mode eq 'perlv' ) { if ( $all =~ /^(.*?%>)(.*)$/s ) { - print W $1; + $w .= $1; $all=$2; $mode = 'html'; next; @@ -51,13 +57,13 @@ foreach $file ( split(/\n/, `find . -depth -print | grep cgi\$`) ) { } elsif ( $mode eq 'perlc' ) { if ( $all =~ /^([^\n]*?)%>(.*)$/s ) { - print W "%$1\n"; + $w .= "%$1\n"; $all=$2; $mode='html'; next; } if ( $all =~ /^([^\n]*)\n(.*)$/s ) { - print W "%$1\n"; + $w .= "%$1\n"; $all=$2; next; } @@ -66,5 +72,9 @@ foreach $file ( split(/\n/, `find . -depth -print | grep cgi\$`) ) { } + system("chmod u+w $file"); + select W; $| = 1; select STDOUT; + open(W,">$file") or die "can't open $file for writing: $!"; + print W $w; close W; } diff --git a/bin/passwd.import b/bin/passwd.import index df53b50ad..8ab9e2ae3 100755 --- a/bin/passwd.import +++ b/bin/passwd.import @@ -1,5 +1,4 @@ #!/usr/bin/perl -Tw -# $Id: passwd.import,v 1.5.4.3 2003-06-12 14:08:02 ivan Exp $ use strict; use vars qw(%part_svc); @@ -76,6 +75,8 @@ while (<SHADOW>) { my($username,$password)=split(/:/); #$password =~ s/^\!$/\*/; #$password =~ s/\!+/\*SUSPENDED\* /; + $password =~ s/^NP$/\*/; + $password =~ s/^\*LK\*$/\*/; $password{$username}=$password; } diff --git a/bin/postfix.export b/bin/postfix.export new file mode 100755 index 000000000..dbb08ceb9 --- /dev/null +++ b/bin/postfix.export @@ -0,0 +1,122 @@ +#!/usr/bin/perl -w + +use strict; +#use File::Path; +use File::Rsync; +use Net::SSH qw(ssh); +use FS::UID qw(adminsuidsetup datasrc); +use FS::Record qw(qsearch); # qsearchs); +use FS::part_export; +#use FS::cust_pkg; +use FS::cust_svc; +#use FS::svc_domain; + +my $user = shift or die &usage; +adminsuidsetup $user; + +my $spooldir = "/usr/local/etc/freeside/export.". datasrc. "/postfix"; +mkdir $spooldir, 0700 unless -d $spooldir; + +my @exports = qsearch('part_export', { 'exporttype' => 'postfix' } ); + +my $rsync = File::Rsync->new({ + rsh => 'ssh', +# dry_run => 1, +}); + +foreach my $export ( @exports ) { + + my $machine = $export->machine; + my $prefix = "$spooldir/$machine"; + mkdir $prefix, 0700 unless -d $prefix; + + #construct %domain hash + + my $mydomain = $export->option('mydomain'); + my %domain; + foreach my $svc_forward ( $export->svc_x ) { + + my( $username, $domain ); + my $srcsvc_acct = $svc_forward->srcsvc_acct; + if ( $srcsvc_acct ) { + ( $username, $domain ) = ( $srcsvc_acct->username, $srcsvc_acct->domain ); + } elsif ( $svc_forward->src =~ /([^@]*)\@([^@]+)$/ ) { + ( $username, $domain ) = ( $1, $2 ); + } else { + die "bad svc_forward record? svcnum ". $svc_forward->svcnum. "\n"; + } + + my( $dusername, $ddomain ); + my $dstsvc_acct = $svc_forward->dstsvc_acct; + if ( $dstsvc_acct ) { + $dusername = $dstsvc_acct->username; + $ddomain = $dstsvc_acct->domain; + } elsif ( $svc_forward->dst =~ /([^@]+)\@([^@]+)$/ ) { + ( $dusername, $ddomain ) = ( $1, $2 ); + } else { + die "bad svc_forward record? svcnum ". $svc_forward->svcnum. "\n"; + } + my $dest; + if ( $ddomain eq $mydomain ) { + $dest = $dusername; + } else { + $dest = "$dusername\@$ddomain"; + } + + push @{$domain{$domain}{$username}}, $dest; + + } + + #write aliases + + my $aliases = delete $domain{$mydomain}; + open(ALIASES, ">$prefix/aliases") or die "can't open $prefix/aliases: $!"; + foreach my $alias ( keys %$aliases ) { + print ALIASES "$alias: ". join(',', @{ $aliases->{$alias} } ). "\n"; + } + close ALIASES; + + #write virtual + + open(VIRTUAL, ">$prefix/virtual") or die "can't open $prefix/virtual: $!"; + foreach my $domain ( keys %domain ) { + print VIRTUAL "$domain DOMAIN\n"; + #foreach my $virtual ( sort { $a ne '' <=> $b ne '' } keys %{$domain{$domain}} ) { + foreach my $virtual ( sort { ( ($b ne '') <=> ($a ne '') ) || $a cmp $b } keys %{$domain{$domain}} ) { + print VIRTUAL "$virtual\@$domain ". + join(',', @{ $domain{$domain}{$virtual} } ). "\n"; + } + print VIRTUAL "\n"; + } + close VIRTUAL; + + #rsync + + my $user = $export->option('user'); + $rsync->exec( { + src => "$prefix/aliases", + dest => "$user\@$machine:". $export->option('aliases'), + } ) or die "rsync to $machine failed: ". join(" / ", $rsync->err); +# warn $rsync->out; + + ssh("$user\@$machine", $export->option('newaliases') || 'newaliases'); +# ssh("$user\@$machine", "postfix reload"); + + $rsync->exec( { + src => "$prefix/virtual", + dest => "$user\@$machine:". $export->option('virtual'), + } ) or die "rsync to $machine failed: ". join(" / ", $rsync->err); +# warn $rsync->out; + ssh("$user\@$machine", $export->option('postmap') + || 'postmap hash:/etc/postfix/virtual'); + ssh("$user\@$machine", $export->option('reload') || 'postfix reload'); + +} + +# ----- + +sub usage { + die "Usage:\n postfix.export user\n"; +} + + diff --git a/bin/postfix_courierimap.import b/bin/postfix_courierimap.import new file mode 100755 index 000000000..12c138b49 --- /dev/null +++ b/bin/postfix_courierimap.import @@ -0,0 +1,137 @@ +#!/usr/bin/perl -Tw + +use strict; +use vars qw(%part_svc %domain_part_svc); +#use Date::Parse; +use DBI; +use Term::Query qw(query); +use FS::UID qw(adminsuidsetup); #datasrc +use FS::Record qw(qsearch qsearchs); +use FS::svc_acct; +use FS::part_svc; +use FS::svc_domain; + +my $user = shift or die &usage; +adminsuidsetup $user; + +#push @FS::svc_acct::shells, qw(/bin/sync /sbin/shutdown /bin/halt /sbin/halt); #others? + +$FS::svc_Common::noexport_hack = 1; +$FS::svc_domain::whois_hack = 1; + +### + +%part_svc=map { $_->svcpart, $_ } qsearch('part_svc',{'svcdb'=>'svc_acct'}); + +die "No services with svcdb svc_acct!\n" unless %part_svc; + +print "\n\n", &menu_svc, "\n", <<END; +Enter part number to import. +END +my $mailbox_svcpart = &getpart; + +%domain_part_svc = map { $_->svcpart, $_ } + qsearch('part_svc', { 'svcdb' => 'svc_domain'} ); + +die "No services with svcdb svc_domain!\n" unless %domain_part_svc; + +print "\n\n", &menu_domain_svc, "\n", <<END; +Enter part number for domains. +END +my $domain_svcpart = &getdomainpart; + +my $datasrc = &getvalue("\n\nEnter the DBI datasource:"); +my $db_user = &getvalue("\n\nEnter the database user:"); +my $db_pass = &getvalue("\n\nEnter the database password:"); + +sub menu_svc { + ( join "\n", map "$_: ".$part_svc{$_}->svc, sort keys %part_svc ). "\n"; +} +sub menu_domain_svc { + ( join "\n", map "$_: ".$domain_part_svc{$_}->svc, sort keys %domain_part_svc ). "\n"; +} +sub getpart { + $^W=0; # Term::Query isn't -w-safe + my $return = query "Enter part number:", 'irk', [ keys %part_svc ]; + $^W=1; + $return; +} +sub getdomainpart { + $^W=0; # Term::Query isn't -w-safe + my $return = query "Enter part number:", 'irk', [ keys %domain_part_svc ]; + $^W=1; + $return; +} +sub getvalue { + my $prompt = shift; + $^W=0; # Term::Query isn't -w-safe + my $return = query $prompt, ''; + $^W=1; + $return; +} + +print "\n\n"; + +### + +my $dbh = DBI->connect( $datasrc, $db_user, $db_pass ) + or die $DBI::errstr; + +my $sth = $dbh->prepare('SELECT username, password, crypt, name, domain FROM mailbox') + or die $dbh->errstr; +$sth->execute or die $sth->errstr; + +my $row; +while ( defined ( $row = $sth->fetchrow_arrayref ) ) { + my( $r_username, $password, $crypt, $finger, $r_domain ) = @$row; + + my( $username, $domain ); + if ( $r_username =~ /^([^@]+)\@([^@]+)$/ ) { + $username = $1; + $domain = $2; + } else { + $username = $r_username; + $domain = $r_domain; + } + my $svc_domain = qsearchs('svc_domain', { 'domain' => $domain } ) + || new FS::svc_domain { + 'domain' => $domain, + 'svcpart' => $domain_svcpart, + 'action' => 'N', + }; + unless ( $svc_domain->svcnum ) { + my $error = $svc_domain->insert; + if ( $error ) { + die "can't insert domain $domain: $error\n"; + } + } + + $password = $crypt if $password eq '*CRYPTED*'; + + $finger =~ s/Outdoor Power.*$/Outdoor Power/; + + my $svc_acct = new FS::svc_acct { + 'svcpart' => $mailbox_svcpart, + 'username' => $username, + 'domsvc' => $svc_domain->svcnum, + '_password' => $password, + 'finger' => $finger, + }; + + my $error = $svc_acct->insert; + #my $error = $svc_acct->check; + if ( $error ) { + if ( $error =~ /duplicate/i ) { + warn "$r_username / $r_domain: $error"; + } else { + die "$r_username / $r_domain: $error"; + } + } + +} + +sub usage { + die "Usage:\n\n postfix_courierimap.import user\n"; +} + + diff --git a/bin/sendmail.import b/bin/sendmail.import new file mode 100644 index 000000000..a55616dc3 --- /dev/null +++ b/bin/sendmail.import @@ -0,0 +1,176 @@ +#!/usr/bin/perl -w + +use strict; +use Term::Query qw(query); +use Net::SCP qw(iscp); +use FS::UID qw(adminsuidsetup datasrc); +use FS::Record qw(qsearch qsearchs); +##use FS::svc_acct_sm; +#use FS::svc_domain; +#use FS::domain_record; +use FS::svc_acct; +##use FS::part_svc; +use FS::svc_forward; +use FS::svc_domain; + +my $user = shift or die &usage; +adminsuidsetup $user; + +#$FS::svc_Common::noexport_hack = 1; +#$FS::domain_record::noserial_hack = 1; + +use vars qw($defaultdomain); +$defaultdomain = 'surferz.net'; + +use vars qw($svcpart $forward_svcpart); +$svcpart = 2; +$forward_svcpart = 4; + +use vars qw($spooldir); +$spooldir = "/usr/local/etc/freeside/export.". datasrc. "/sendmail"; +mkdir($spooldir, 0755) unless -d $spooldir; + +print "\n\n", <<END; +Enter the location and name of your Sendmail aliases file, for example +"mail.isp.com:/etc/mail/aliases" +END +my($aliases)=&getvalue(":"); + +use vars qw($aliases_machine $aliases_prefix); +$aliases_machine = (split(/:/, $aliases))[0]; +$aliases_prefix = "$spooldir/$aliases_machine"; +mkdir($aliases_prefix, 0755) unless -d $aliases_prefix; + +#iscp("root\@$aliases","$aliases_prefix/aliases.import"); +iscp("ivan\@$aliases","$aliases_prefix/aliases.import"); + +print "\n\n", <<END; +Enter the location and name of your Sendmail virtusertable directory, for example +"mail.isp.com:/etc/mail/virtusertable" +END +my($virtusertable)=&getvalue(":"); + +use vars qw($virtusertable_machine $virtusertable_prefix); +$virtusertable_machine = (split(/:/, $virtusertable))[0]; +$virtusertable_prefix = "$spooldir/$virtusertable_machine"; +mkdir($virtusertable_prefix, 0755) unless -d $virtusertable_prefix; +mkdir("$virtusertable_prefix/virtusertable.import", 0755) + unless -d "$virtusertable_prefix/virtusertable.import"; + +#iscp("root\@$virtusertable/*","$aliases_prefix/virtusertable.import/"); +iscp("ivan\@$virtusertable/*","$aliases_prefix/virtusertable.import/"); + +sub getvalue { + my $prompt = shift; + $^W=0; # Term::Query isn't -w-safe + my $return = query $prompt, ''; + $^W=1; + $return; +} + +print "\n\n"; + +## + +foreach my $file ( + "$aliases_prefix/aliases.import", + glob("$aliases_prefix/virtusertable.import/*"), +) { + + warn "importing $file\n"; + + open(FILE,"<$file") or die $!; + while (<FILE>) { + next if /^\s*#/ || /^\s*$/; #skip comments & blank lines + + unless ( /^([\w\@\.\-]+)[:\s]\s*(.*\S)\s*$/ ) { + warn "Unparsable line: $_"; + next; + } + my($rawusername, $rawdest) = ($1, $2); + + my($username, $domain); + if ( $rawusername =~ /^([\w\-\.\&]*)\@([\w\.\-]+)$/ ) { + $username = $1; + $domain = $2; + } elsif ( $rawusername =~ /\@/ ) { + die "Unparsable username: $rawusername\n"; + } else { + $username = $rawusername; + $domain = $defaultdomain; + } + + #find svc_acct record or set $src + my($srcsvc, $src) = &svcnum_or_literal($username, $domain); + + foreach my $dest ( split(/,/, $rawdest) ) { + + my($dusername, $ddomain); + if ( $dest =~ /^([\w\-\.\&]+)\@([\w\.\-]+)$/ ) { + $dusername = $1; + $ddomain = $2; + } elsif ( $dest =~ /\@/ ) { + die "Unparsable username: $dest\n"; + } else { + $dusername = $dest; + $ddomain = $defaultdomain; + } + my($dstsvc, $dst) = &svcnum_or_literal($dusername, $ddomain); + + my $svc_forward = new FS::svc_forward ({ + svcpart => $forward_svcpart, + srcsvc => $srcsvc, + src => $src, + dstsvc => $dstsvc, + dst => $dst, + }); + my $error = $svc_forward->insert; + #my $error = $svc_forward->check; + if ( $error ) { + die "$rawusername: $rawdest: $error\n"; + } + } + + + } #next entry + +} #next file + +## + +sub svcnum_or_literal { + my($username, $domain) = @_; + + my $svc_domain = qsearchs('svc_domain', { 'domain' => $domain } ); + my $domsvc = $svc_domain ? $svc_domain->svcnum : ''; + + my @svc_acct = grep { $_->cust_svc->svcpart == $svcpart } + qsearch('svc_acct', { + 'username' => $username, + 'domsvc' => $domsvc, + }); + + if ( scalar(@svc_acct) > 1 ) { + die "multiple sources found for $username\@$domain !\n"; + } + + my( $svcnum, $literal ) = ('', ''); + if ( @svc_acct ) { + my $svc_acct = $svc_acct[0]; + $svcnum = $svc_acct->svcnum; + } else { + $literal = "$username\@$domain"; + } + + return( $svcnum, $literal ); + +} + +sub usage { + die "Usage:\n\n sendmail.import user\n"; +} + + + + + diff --git a/bin/shadow.reimport b/bin/shadow.reimport new file mode 100755 index 000000000..7957011eb --- /dev/null +++ b/bin/shadow.reimport @@ -0,0 +1,125 @@ +#!/usr/bin/perl -w +# +# -d: dry-run: make no changes +# -r: replace: overwrite existing passwords (otherwise only "*" passwords will +# be changed) +# -b: blowfish replace: overwrite existing passwords only if they are +# blowfish-encrypted + +use strict; +use vars qw(%part_svc); +use Getopt::Std; +use Term::Query qw(query); +use Net::SCP qw(iscp); +use FS::UID qw(adminsuidsetup datasrc); +use FS::Record qw(qsearch qsearchs); +use FS::svc_acct; +use FS::part_svc; + +use vars qw($opt_d $opt_r $opt_b); +getopts("drb"); + +my $user = shift or die &usage; +adminsuidsetup $user; + +push @FS::svc_acct::shells, qw(/bin/sync /sbin/shutdown /bin/halt /sbin/halt); #others? + +my($spooldir)="/usr/local/etc/freeside/export.". datasrc; + +#$FS::svc_acct::nossh_hack = 1; +$FS::svc_Common::noexport_hack = 1; + +### + +%part_svc=map { $_->svcpart, $_ } qsearch('part_svc',{'svcdb'=>'svc_acct'}); + +die "No services with svcdb svc_acct!\n" unless %part_svc; + +print "\n\n", &menu_svc, "\n", <<END; +Enter part number or part numbers to import. +END +my($shell_svcpart)=&getvalue; +my @shell_svcpart = split(/[,\s]+/, $shell_svcpart); + +print "\n\n", <<END; +Enter the location and name of your _user_ shadow file, for example +"mail.isp.com:/etc/shadow" or "bsd.isp.com:/etc/master.passwd" +END +my($loc_shadow)=&getvalue(":"); +iscp("root\@$loc_shadow", "$spooldir/shadow.import"); + +sub menu_svc { + ( join "\n", map "$_: ".$part_svc{$_}->svc, sort keys %part_svc ). "\n"; +} +sub getpart { + $^W=0; # Term::Query isn't -w-safe + my $return = query "Enter part number:", 'irk', [ keys %part_svc ]; + $^W=1; + $return; +} +sub getvalue { + my $prompt = shift; + $^W=0; # Term::Query isn't -w-safe + my $return = query $prompt, ''; + $^W=1; + $return; +} + +print "\n\n"; + +### + +open(SHADOW,"<$spooldir/shadow.import"); + +my($line, $updated); +while (<SHADOW>) { + $line++; + chop; + my($username,$password)=split(/:/); + +# my @svc_acct = grep { $_->cust_svc->svcpart == $shell_svcpart } +# qsearch('svc_acct', { 'username' => $username } ); + my @svc_acct = grep { + my $svcpart = $_->cust_svc->svcpart; + grep { $_ == $svcpart } @shell_svcpart; + } qsearch('svc_acct', { 'username' => $username } ); + + next unless @svc_acct; + + if ( scalar(@svc_acct) > 1 ) { + die "more than one $username found!\n"; + next; + } + + my $svc_acct = shift @svc_acct; + + next unless $svc_acct->_password eq '*' + || $opt_r + || ( $opt_b && $svc_acct->_password =~ /^\$2a?\$/ ); + + next if $svc_acct->username eq 'root'; + + next if $password eq 'NP' || $password eq '*LK*'; + + next if $svc_acct->_password eq $password; + next if $svc_acct->_password =~ /^\*SUSPENDED\*/; + + my $new_svc_acct = new FS::svc_acct( { $svc_acct->hash } ); + $new_svc_acct->_password($password); + #warn "$username: ". $svc_acct->_password. " -> $password\n"; + warn "changing password for $username\n"; + unless ( $opt_d ) { + my $error = $new_svc_acct->replace($svc_acct); + die "$username: $error" if $error; + } + + $updated++; + +} + +warn "$updated of $line passwords changed\n"; + +sub usage { + die "Usage:\n\n shadow.reimport [ -d ] [ -r ] user\n"; +} + diff --git a/bin/sqlradius.import b/bin/sqlradius.import new file mode 100644 index 000000000..e75f65b17 --- /dev/null +++ b/bin/sqlradius.import @@ -0,0 +1,152 @@ +#!/usr/bin/perl -Tw + +use strict; +use vars qw(%part_svc %domain_part_svc); +#use Date::Parse; +use DBI; +use Term::Query qw(query); +use FS::UID qw(adminsuidsetup); #datasrc +use FS::Record qw(qsearch qsearchs); +use FS::svc_acct; +use FS::part_svc; +use FS::svc_domain; + +my $user = shift or die &usage; +adminsuidsetup $user; + +#push @FS::svc_acct::shells, qw(/bin/sync /sbin/shutdown /bin/halt /sbin/halt); #others? + +$FS::svc_Common::noexport_hack = 1; +$FS::svc_domain::whois_hack = 1; + +### + +%part_svc=map { $_->svcpart, $_ } qsearch('part_svc',{'svcdb'=>'svc_acct'}); + +die "No services with svcdb svc_acct!\n" unless %part_svc; + +print "\n\n", &menu_svc, "\n", <<END; +Enter part number to import. +END +my $sqlradius_svcpart = &getpart; + +%domain_part_svc = map { $_->svcpart, $_ } + qsearch('part_svc', { 'svcdb' => 'svc_domain'} ); + +die "No services with svcdb svc_domain!\n" unless %domain_part_svc; + +print "\n\n", &menu_domain_svc, "\n", <<END; +Enter part number for domains. +END +my $domain_svcpart = &getdomainpart; + +my $datasrc = &getvalue("\n\nEnter the DBI datasource:"); +my $db_user = &getvalue("\n\nEnter the database user:"); +my $db_pass = &getvalue("\n\nEnter the database password:"); + +sub menu_svc { + ( join "\n", map "$_: ".$part_svc{$_}->svc, sort keys %part_svc ). "\n"; +} +sub menu_domain_svc { + ( join "\n", map "$_: ".$domain_part_svc{$_}->svc, sort keys %domain_part_svc ). "\n"; +} +sub getpart { + $^W=0; # Term::Query isn't -w-safe + my $return = query "Enter part number:", 'irk', [ keys %part_svc ]; + $^W=1; + $return; +} +sub getdomainpart { + $^W=0; # Term::Query isn't -w-safe + my $return = query "Enter part number:", 'irk', [ keys %domain_part_svc ]; + $^W=1; + $return; +} +sub getvalue { + my $prompt = shift; + $^W=0; # Term::Query isn't -w-safe + my $return = query $prompt, ''; + $^W=1; + $return; +} + +print "\n\n"; + +### + +my $dbh = DBI->connect( $datasrc, $db_user, $db_pass ) + or die $DBI::errstr; + +my $sth = $dbh->prepare('SELECT DISTINCT UserName, Realm FROM radcheck') + or die $dbh->errstr; +$sth->execute or die $sth->errstr; + +my $row; +while ( defined ( $row = $sth->fetchrow_arrayref ) ) { + my( $r_username, $realm ) = @$row; + + my( $username, $domain ); + if ( $r_username =~ /^([^@]+)\@([^@]+)$/ ) { + $username = $1; + $domain = $2; + } else { + $username = $r_username; + $domain = $realm; + } + my $svc_domain = qsearchs('svc_domain', { 'domain' => $domain } ) + || new FS::svc_domain { + 'domain' => $domain, + 'svcpart' => $domain_svcpart, + 'action' => 'N', + }; + unless ( $svc_domain->svcnum ) { + my $error = $svc_domain->insert; + if ( $error ) { + die "can't insert domain $domain: $error\n"; + } + } + + my( $password, $finger, $group ) = ( '', '', '' ); + + my $rc_sth = $dbh->prepare( + 'SELECT Attribute, Value, Name, GroupName'. + ' FROM radcheck'. + ' WHERE UserName = ? and Realm = ?' + ) or die $dbh->errstr; + $rc_sth->execute($r_username, $realm) or die $rc_sth->errstr; + + foreach my $rc_row ( @{$rc_sth->fetchall_arrayref} ) { + my($attribute, $value, $name, $groupname) = @$rc_row; + if ( $attribute =~ /^((User|Crypt)-)?Password$/ ) { + $password = $value; + $finger = $name; + $group = $groupname; + } else { + #handle other params! + } + } + + my $svc_acct = new FS::svc_acct { + 'svcpart' => $sqlradius_svcpart, + 'username' => $username, + 'domsvc' => $svc_domain->svcnum, + '_password' => $password, + 'finger' => $finger, + }; + + my $error = $svc_acct->insert; + #my $error = $svc_acct->check; + if ( $error ) { + if ( $error =~ /duplicate/i ) { + warn "$r_username / $realm: $error"; + } else { + die "$r_username / $realm: $error"; + } + } + +} + +sub usage { + die "Usage:\n\n sqlradius.import user\n"; +} + diff --git a/bin/sqlradius.reimport b/bin/sqlradius.reimport new file mode 100755 index 000000000..89eb8018b --- /dev/null +++ b/bin/sqlradius.reimport @@ -0,0 +1,156 @@ +#!/usr/bin/perl -Tw + +use strict; +use vars qw(%part_svc %domain_part_svc); +#use Date::Parse; +use DBI; +use Term::Query qw(query); +use FS::UID qw(adminsuidsetup); #datasrc +use FS::Record qw(qsearch qsearchs); +use FS::svc_acct; +use FS::part_svc; +use FS::svc_domain; + +my $user = shift or die &usage; +adminsuidsetup $user; + +#push @FS::svc_acct::shells, qw(/bin/sync /sbin/shutdown /bin/halt /sbin/halt); #others? + +$FS::svc_Common::noexport_hack = 1; +$FS::svc_domain::whois_hack = 1; + +### + +%part_svc=map { $_->svcpart, $_ } qsearch('part_svc',{'svcdb'=>'svc_acct'}); + +die "No services with svcdb svc_acct!\n" unless %part_svc; + +print "\n\n", &menu_svc, "\n", <<END; +Enter part number to import. +END +my $sqlradius_svcpart = &getpart; + +%domain_part_svc = map { $_->svcpart, $_ } + qsearch('part_svc', { 'svcdb' => 'svc_domain'} ); + +die "No services with svcdb svc_domain!\n" unless %domain_part_svc; + +print "\n\n", &menu_domain_svc, "\n", <<END; +Enter part number for domains. +END +my $domain_svcpart = &getdomainpart; + +my $datasrc = &getvalue("\n\nEnter the DBI datasource:"); +my $db_user = &getvalue("\n\nEnter the database user:"); +my $db_pass = &getvalue("\n\nEnter the database password:"); + +sub menu_svc { + ( join "\n", map "$_: ".$part_svc{$_}->svc, sort keys %part_svc ). "\n"; +} +sub menu_domain_svc { + ( join "\n", map "$_: ".$domain_part_svc{$_}->svc, sort keys %domain_part_svc ). "\n"; +} +sub getpart { + $^W=0; # Term::Query isn't -w-safe + my $return = query "Enter part number:", 'irk', [ keys %part_svc ]; + $^W=1; + $return; +} +sub getdomainpart { + $^W=0; # Term::Query isn't -w-safe + my $return = query "Enter part number:", 'irk', [ keys %domain_part_svc ]; + $^W=1; + $return; +} +sub getvalue { + my $prompt = shift; + $^W=0; # Term::Query isn't -w-safe + my $return = query $prompt, ''; + $^W=1; + $return; +} + +print "\n\n"; + +### + +my $dbh = DBI->connect( $datasrc, $db_user, $db_pass ) + or die $DBI::errstr; + +my $sth = $dbh->prepare('SELECT DISTINCT UserName, Realm FROM radcheck') + or die $dbh->errstr; +$sth->execute or die $sth->errstr; + +my $row; +while ( defined ( $row = $sth->fetchrow_arrayref ) ) { + my( $r_username, $realm ) = @$row; + + my( $username, $domain ); + if ( $r_username =~ /^([^@]+)\@([^@]+)$/ ) { + $username = $1; + $domain = $2; + } else { + $username = $r_username; + $domain = $realm; + } + my $svc_domain = qsearchs('svc_domain', { 'domain' => $domain } ) + || new FS::svc_domain { + 'domain' => $domain, + 'svcpart' => $domain_svcpart, + 'action' => 'N', + }; + unless ( $svc_domain->svcnum ) { + die "new domain? wtf"; + my $error = $svc_domain->insert; + if ( $error ) { + die "can't insert domain $domain: $error\n"; + } + } + + my( $password, $finger, $group ) = ( '', '', '' ); + + my $rc_sth = $dbh->prepare( + 'SELECT Attribute, Value, Name, GroupName'. + ' FROM radcheck'. + ' WHERE UserName = ? and Realm = ?' + ) or die $dbh->errstr; + $rc_sth->execute($r_username, $realm) or die $rc_sth->errstr; + + foreach my $rc_row ( @{$rc_sth->fetchall_arrayref} ) { + my($attribute, $value, $name, $groupname) = @$rc_row; + if ( $attribute =~ /^(Crypt-)?Password$/ ) { + $password = $value; + $finger = $name; + $group = $groupname; + } else { + #handle other params! + } + } + + my @svc_acct = grep { $_->cust_svc->svcpart == $sqlradius_svcpart } + qsearch('svc_acct', { 'username' => $username, + 'domsvc' => $svc_domain->svcnum, } ); + + print "$r_username / $realm: $password / $finger: "; + if ( scalar(@svc_acct) == 0 ) { + print "not found\n"; + next; + } elsif ( scalar(@svc_acct) > 1 ) { + print "multiple matches found?!?!\n"; + next; + } else { + print "correcting password and name\n"; + } + + my $svc_acct = $svc_acct[0]; + my $new = new FS::svc_acct { $svc_acct->hash, '_password' => $password, 'finger' => $finger }; + my $error = $new->replace($svc_acct); + #my $error = $new->check; + die "$r_username / $realm: $error" if $error; + +} + +sub usage { + die "Usage:\n\n sqlradius.import user\n"; +} + |