#!/usr/bin/perl use warnings; use strict; use DBI; use Getopt::Long; use Passwd::Unix qw(check_sanity reset encpass passwd_file shadow_file group_file backup warnings del del_user uid gid gecos home shell passwd rename maxgid maxuid exists_user exists_group user users users_from_shadow del_group group groups groups_from_gshadow); use File::Path qw( make_path ); use Config::Crontab; use Data::Dumper qw(Dumper); my $db_adm = 'ase_lar'; my $db_adm_usr = 'ase_lar'; my $db_root_pwd = 'Ase@22500'; my $db_adm_pwd = 'laravel'; my $db_adm_srv = 'www.aseltd.eu'; my ( $company, $company_id, $company_name ); my ( $company_db_name, $company_db_user, $company_db_pwd ); my ( $company_os_user, $company_os_pwd ); my $company_os_grp = '1005'; #group aseuser sub getTimeStamp { #parm [ts] => timestamp for filename # [log] => timestamp for log # [db_ts] => timestamp for db; my $format = "%04d%02d%02d%02d%02d%02d"; my ($p1) = @_; if ( defined $p1 and $p1 eq "log" ) { $format = "%04d%02d%02d %02d:%02d:%02d"; } if ( defined $p1 and $p1 eq "db_ts" ) { $format = "%04d-%02d-%02d %02d:%02d:%02d"; } my ( $sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst ) = localtime(time); my $timestamp = sprintf( $format, $year + 1900, $mon + 1, $mday, $hour, $min, $sec ); return $timestamp; } sub generateRandomPassword { my $passwordsize = shift; my @alphanumeric = ( 'a' .. 'z', 'A' .. 'Z', 0 .. 9 ); my $randpassword = join '', map $alphanumeric[ rand @alphanumeric ], 0 .. ( $passwordsize - 1 ); return $randpassword; } sub checkCompanyDBSet { my $dbh = DBI->connect( "DBI:mysql:$db_adm;host=$db_adm_srv", $db_adm_usr, $db_adm_pwd ) or die getTimeStamp("log") . " - pid $$ >> Could not connect to admin database: $DBI::errstr"; my $sth = $dbh->prepare( "select id, name, db_user, db_pwd, db_name, os_user, os_pwd from " . "ase_lar.companies where name_short like '" . $company . "%';" ) or die getTimeStamp("log") . " - pid $$ >> $DBI::errstr"; $sth->execute(); if ( $sth->rows < 0 ) { die getTimeStamp("log") . " - pid $$ >> No company selected.\n"; } elsif ( $sth->rows > 1 ) { die getTimeStamp("log") . " - pid $$ >> Too many company selected.\n"; } else { my $results = $sth->fetchrow_hashref; $company_name = $results->{'name'}; $company_id = $results->{'id'}; $company_db_name = $results->{'db_name'}; $company_db_user = $results->{'db_user'}; $company_db_pwd = $results->{'db_pwd'}; $company_os_user = $results->{'os_user'}; $company_os_pwd = $results->{'os_pwd'}; print getTimeStamp("log") . " - pid $$ >> Selected company: " . $company_name . ".\n"; } $sth->finish; if ( $company_db_name and $company_db_user and $company_db_pwd ) { return 1; } } sub setCompanyDBSet { my $dbh = DBI->connect( "DBI:mysql:$db_adm;host=$db_adm_srv", $db_adm_usr, $db_adm_pwd ) or die getTimeStamp("log") . " - pid $$ >> Could not connect to admin database: $DBI::errstr"; $company_db_user = sprintf "dbu%08s", $company_id; $company_db_name = sprintf "dbn%08s", $company_id; $company_db_pwd = generateRandomPassword(16); my $sth = $dbh->prepare( "update ase_lar.companies set db_user = '" . $company_db_user . "', db_pwd = '" . $company_db_pwd . "', db_name = '" . $company_db_name . "' where id = " . $company_id . ";" ) or die getTimeStamp("log") . " - pid $$ >> $DBI::errstr"; $sth->execute() or die getTimeStamp("log") . " - pid $$ >> $DBI::errstr"; $sth->finish; return 1; } sub checkCompanyDBGrant() { my $exit_rc = 1; my $dbh = DBI->connect( "DBI:mysql:$db_adm;host=$db_adm_srv", 'root', $db_root_pwd ) or die getTimeStamp("log") . " - pid $$ >> Could not connect to db server: $DBI::errstr"; my $sth = $dbh->prepare( "show grants for '" . $company_db_user . "'\@'localhost';" ) or die getTimeStamp("log") . " - pid $$ >> $DBI::errstr"; if ( !$sth->execute() ) { print getTimeStamp("log") . " - pid $$ >> $DBI::errstr\n"; $exit_rc = 0; } else { my $results = $sth->fetchall_arrayref; my @arr_res = @{$results}; if ( @arr_res == 1 ) { $exit_rc = 0 } } $sth->finish; return $exit_rc; } sub setCompanyDBGrant() { my $dbh = DBI->connect( "DBI:mysql:$db_adm;host=$db_adm_srv", 'root', $db_root_pwd ) or die getTimeStamp("log") . " - pid $$ >> Could not connect to db server: $DBI::errstr"; my $sth_db = $dbh->prepare( "CREATE DATABASE IF NOT EXISTS " . $company_db_name . " CHARACTER SET utf8 COLLATE utf8_general_ci;" ) or die getTimeStamp("log") . " - pid $$ >> $DBI::errstr"; $sth_db->execute() or die getTimeStamp("log") . " - pid $$ >> $DBI::errstr"; $sth_db->finish; my $sth_user = $dbh->prepare( "CREATE USER IF NOT EXISTS '" . $company_db_user . "'\@'localhost' IDENTIFIED BY '" . $company_db_pwd . "';" ) or die getTimeStamp("log") . " - pid $$ >> $DBI::errstr"; $sth_user->execute() or die getTimeStamp("log") . " - pid $$ >> $DBI::errstr"; $sth_user->finish; my $sth_grant = $dbh->prepare( "GRANT ALL PRIVILEGES ON " . $company_db_name . ".* TO '" . $company_db_user . "'\@'localhost' WITH GRANT OPTION;" ) or die getTimeStamp("log") . " - pid $$ >> $DBI::errstr"; $sth_grant->execute() or die getTimeStamp("log") . " - pid $$ >> $DBI::errstr"; $sth_grant->finish; return 1; } sub setCompanyDBTables() { my $dbh = DBI->connect( "DBI:mysql:$db_adm;host=$db_adm_srv", 'root', $db_root_pwd ) or die getTimeStamp("log") . " - pid $$ >> Could not connect to db server: $DBI::errstr"; my $sth_db = $dbh->prepare( "CREATE DATABASE IF NOT EXISTS " . $company_db_name . " CHARACTER SET utf8 COLLATE utf8_general_ci;" ) or die getTimeStamp("log") . " - pid $$ >> $DBI::errstr"; $sth_db->execute() or die getTimeStamp("log") . " - pid $$ >> $DBI::errstr"; $sth_db->finish; my $sth_tb = $dbh->prepare( "SELECT table_name, table_type FROM information_schema.tables WHERE table_schema='" . $db_adm . "' ORDER BY table_type ASC;" ) or die getTimeStamp("log") . " - pid $$ >> $DBI::errstr"; $sth_tb->execute() or die getTimeStamp("log") . " - pid $$ >> $DBI::errstr"; my $tables_list = $sth_tb->fetchall_arrayref; foreach my $table ( @{$tables_list} ) { if ( $table->[1] eq 'BASE TABLE' ) { #table my $sth_deft = $dbh->prepare( "CREATE TABLE IF NOT EXISTS " . $company_db_name . "." . $table->[0] . " LIKE " . $db_adm . "." . $table->[0] . ";" ) or die getTimeStamp("log") . " - pid $$ " . $table->[0] . " >> $DBI::errstr"; $sth_deft->execute() or die getTimeStamp("log") . " - pid $$ " . $table->[0] . " >> $DBI::errstr"; $sth_deft->finish; if ( $table->[0] ne 'ELABDATADISP' and $table->[0] ne 'RAWDATACOR' and $table->[0] ne 'companies' and $table->[0] ne 'sites' ) { my $sth_cpyt = $dbh->prepare( "INSERT " . $company_db_name . "." . $table->[0] . " SELECT * FROM " . $db_adm . "." . $table->[0] . ";" ) or die getTimeStamp("log") . " - pid $$ " . $table->[0] . " >> $DBI::errstr"; $sth_cpyt->execute() or die getTimeStamp("log") . " - pid $$ " . $table->[0] . " >> $DBI::errstr"; $sth_cpyt->finish; } elsif ( $table->[0] eq 'companies' ) { my $sth_cpyt = $dbh->prepare( "INSERT " . $company_db_name . "." . $table->[0] . " SELECT * FROM " . $db_adm . "." . $table->[0] . " WHERE id = " . $company_id . ";" ) or die getTimeStamp("log") . " - pid $$ " . $table->[0] . " >> $DBI::errstr"; $sth_cpyt->execute() or die getTimeStamp("log") . " - pid $$ " . $table->[0] . " >> $DBI::errstr"; $sth_cpyt->finish; } elsif ( $table->[0] eq 'sites' ) { my $sth_cpyt = $dbh->prepare( "INSERT " . $company_db_name . "." . $table->[0] . " SELECT * FROM " . $db_adm . "." . $table->[0] . " WHERE company_id = " . $company_id . ";" ) or die getTimeStamp("log") . " - pid $$ " . $table->[0] . " >> $DBI::errstr"; $sth_cpyt->execute() or die getTimeStamp("log") . " - pid $$ " . $table->[0] . " >> $DBI::errstr"; $sth_cpyt->finish; } } elsif ( $table->[1] eq 'VIEW' ) { #view $dbh->do( "USE " . $company_db_name . ";" ); my $sth_views = $dbh->prepare( "SHOW CREATE VIEW " . $db_adm . "." . $table->[0] . ";" ) or die getTimeStamp("log") . " - pid $$ " . $table->[0] . " >> $DBI::errstr"; $sth_views->execute() or die getTimeStamp("log") . " - pid $$ " . $table->[0] . " >> $DBI::errstr"; my $view_def = $sth_views->fetchall_arrayref; $sth_views->finish; $view_def->[0]->[1] =~ s/$db_adm/$company_db_name/g; my $sth_viewd = $dbh->prepare( $view_def->[0]->[1] ) or die getTimeStamp("log") . " - pid $$ " . $table->[0] . " >> $DBI::errstr"; $sth_viewd->execute() or die getTimeStamp("log") . " - pid $$ " . $table->[0] . " >> $DBI::errstr"; $sth_viewd->finish; } } $sth_tb->finish; } sub setCompanyOSSet { my $dbh = DBI->connect( "DBI:mysql:$db_adm;host=$db_adm_srv", $db_adm_usr, $db_adm_pwd ) or die getTimeStamp("log") . " - pid $$ >> Could not connect to admin database: $DBI::errstr"; $company_os_user = sprintf "aseu%08s", $company_id; $company_os_pwd = generateRandomPassword(16); my $sth = $dbh->prepare( "update ase_lar.companies set os_user = '" . $company_os_user . "', os_pwd = '" . $company_os_pwd . "' where id = " . $company_id . ";" ) or die getTimeStamp("log") . " - pid $$ >> $DBI::errstr"; $sth->execute() or die getTimeStamp("log") . " - pid $$ >> $DBI::errstr"; $sth->finish; if ( !user( $company_os_user, encpass($company_os_pwd), maxuid() + 1, $company_os_grp, $company_name . " user", "/home/" . $company_os_user, "/bin/ftponly" ) ) { die getTimeStamp("log") . " - pid $$ >> Error in user definition\n"; } if ( !-d "/home/" . $company_os_user ) { make_path "/home/" . $company_os_user, { mode => 0755, owner => $company_os_user, group => $company_os_grp } or warn getTimeStamp("log") . " >> Failed to create path: /home/" . $company_os_user . "\n"; } print getTimeStamp("log") . " - pid $$ >> Create mysql asepath for os user.\n"; my @args = ( "/bin/su -c 'mysql_config_editor set --login-path=asepath --host=localhost --user=root --password' - " . $company_os_user ); system(@args) == 0 or die( getTimeStamp("log") . " - pid $$ >> system @args failed: $?\n" ); print getTimeStamp("log") . " - pid $$ >> Add crontab db backup.\n"; my $cron = new Config::Crontab( -owner => 'asega' ); $cron->read; $cron->last( new Config::Crontab::Block( -data => "0 1 * * * /usr/bin/mysqldump --login-path=asepath --net_buffer_length=4096 " . $company_db_name . " | /bin/bzip2 -c > /home/asega/db_dumps/backup-" . $company_db_name . "-\$(\$TIMESTAMP).sql.bz2 2>> /home/asega/log/dump_db.log" ) ); $cron->write; return 1; } print getTimeStamp("log") . " - pid $$ >> Execution started.\n"; GetOptions( "company=s" => \$company ) or die("Error in command line arguments\n"); if ( !checkCompanyDBSet() ) { print getTimeStamp("log") . " - pid $$ >> Set Company DB set.\n"; setCompanyDBSet(); } if ( !checkCompanyDBGrant() ) { print getTimeStamp("log") . " - pid $$ >> Set Company user DB grant.\n"; setCompanyDBGrant(); print getTimeStamp("log") . " - pid $$ >> Set Company user DB tables.\n"; setCompanyDBTables(); } if ( !defined $company_os_user or !exists_user($company_os_user) ) { print getTimeStamp("log") . " - pid $$ >> Create os user.\n"; setCompanyOSSet(); } print getTimeStamp("log") . " - pid $$ >> Execution ended.\n"; exit;