#!/usr/local/bin/perl # import.cgi # Work out what will be imported, and either tell the user or actually do it require './virtual-server-lib.pl'; &can_import_servers() || &error($text{'import_ecannot'}); &ReadParse(); &ui_print_header(undef, $text{'import_title'}, ""); # Check for domain clash $in{'dom'} = lc($in{'dom'}); @doms = &list_domains(); ($clash) = grep { $_->{'dom'} eq $in{'dom'} } @doms; $clash && &error_exit($text{'import_eexists'}); # Get the parent if (!$in{'parent_def'}) { $parent = &get_domain_by("user", $in{'parent'}, "parent", ""); } # Validate username and group name if (!$parent) { $in{'user_def'} || $in{'user'} =~ /^[^\t :]+$/ || &error_exit($text{'setup_euser2'}); $in{'group_def'} || $in{'group'} =~ /^[^\t :]+$/ || &error_exit($text{'import_egroup'}); # Validate quota if (&has_home_quotas()) { if ($in{'quota'} == -1) { $in{'quota'} = $in{'otherquota'} }; $in{'quota'} =~ /^[0-9\.]+$/ || &error($text{'setup_equota'}); } } # Make sure IP is valid if ($in{'virt'}) { &foreign_require("net", "net-lib.pl"); ($iface) = grep { $_->{'address'} eq $in{'ip'} } ( &net::boot_interfaces(), &net::active_interfaces() ); $iface || &error_exit($text{'import_enoip'}); $iface->{'address'} eq &get_default_ip() && &error_exit($text{'import_eipsame'}); foreach $d (@doms) { $d->{'ip'} eq $in{'ip'} && &error_exit(&text('import_eipclash', $d->{'dom'})); } $iface->{'virtual'} eq '' && &error_exit(&text('import_ereal', $iface->{'fullname'})); } # Validate home directory if (!$in{'home_def'}) { -d $in{'home'} && $in{'home'} =~ /^\/\S/ || &error($text{'import_ehome'}); } # Validate prefix if (!$in{'prefix_def'}) { $in{'prefix'} =~ /^[a-z0-9\.\-]+$/i || &error($text{'setup_eprefix'}); $prefix = $in{'prefix'}; } else { $prefix = &compute_prefix($in{'dom'}, $in{'crgroup'} || $in{'group'}, $parent); } # Validate regexp if (!$in{'regexp_def'}) { $in{'regexp'} =~ /\S/ || &error($text{'import_eregexp'}); } if ($in{'confirm'}) { # Go ahead and do it &lock_domain_name($in{'dom'}); print "$text{'import_doing'}

\n"; &require_useradmin(); if (!$parent) { # Get existing group and user details $crgroup = $in{'crgroup'} || $in{'group'}; @groups = &foreign_call($usermodule, "list_groups"); ($ginfo) = grep { $_->{'group'} eq $crgroup } @groups; &build_group_taken(\%gtaken, \%ggtaken); $gid = $ginfo ? $ginfo->{'gid'} : &allocate_gid(\%gtaken); $cruser = $in{'cruser'} || $in{'user'}; @users = &foreign_call($usermodule, "list_users"); ($uinfo) = grep { $_->{'user'} eq $cruser } @users; &build_taken(\%taken, \%utaken); $uid = $uinfo ? $uinfo->{'uid'} : &allocate_uid(\%taken); $ugid = $uinfo ? $uinfo->{'gid'} : $gid; $ugroup = $uinfo ? getgrgid($uinfo->{'gid'}) : $crgroup; $owner = $uinfo ? $uinfo->{'real'} : "Imported domain $in{'dom'}"; } else { # All details come from parent $cruser = $parent->{'user'}; $crgroup = $parent->{'group'}; $uid = $parent->{'uid'}; $gid = $parent->{'gid'}; $ugid = $parent->{'ugid'}; $ugroup = $parent->{'ugroup'}; $owner = "Imported domain $in{'dom'}"; } # Create domain details %found = map { $_, 1 } split(/\0/, $in{'found'}); @dbs = ( split(/\s+/, $in{'db_mysql'}), split(/\s+/, $in{'db_postgres'}) ); %dom = ( 'id', &domain_id(), 'dom', $in{'dom'}, 'unix', $parent ? 0 : 1, 'dir', 1, 'user', $cruser, 'group', $crgroup, 'ugroup', $ugroup, 'uid', $uid, 'gid', $gid, 'ugid', $ugid, 'prefix', $prefix, 'owner', $owner, 'mail', int($found{'mail'}), 'web', int($found{'web'}), 'web_port', $found{'web'} ? $default_web_port : undef, 'ssl', int($found{'ssl'}), 'web_sslport', $found{'ssl'} ? $default_web_sslport : undef, 'ftp', int($found{'ftp'}), 'webalizer', int($found{'webalizer'}), 'mysql', int($found{'mysql'}), 'postgres', int($found{'postgres'}), 'logrotate', int($found{'logrotate'}), 'webmin', $parent ? 0 : $in{'webmin'}, 'name', !$in{'virt'}, 'ip', $in{'ip'}, 'iface', $in{'virt'} ? $iface->{'fullname'} : "", 'virt', $in{'virt'}, 'dns', int($found{'dns'}), 'pass', $parent ? $parent->{'pass'} : $in{'pass'}, 'db', $dbs[0], 'db_mysql', $in{'found_mysql'}, 'db_postgres', $in{'found_postgres'}, 'source', 'import.cgi', 'parent', $parent ? $parent->{'id'} : undef, 'template', 0, 'reseller', undef, ); foreach $f (@feature_plugins) { $dom{$f} = int($found{$f}); } $tmpl = &get_template(0); if (!$parent) { &set_limits_from_template(\%dom, $tmpl); $dom{'quota'} = $dom{'uquota'} = "a_parse('quota', "home"); &set_capabilities_from_template(\%dom, $tmpl); } $dom{'emailto'} = $dom{'email'} || $dom{'user'}.'@'.&get_system_hostname(); # Work out home directory $dom{'home'} = !$in{'home_def'} ? $in{'home'} : $uinfo ? $uinfo->{'home'} : &server_home_directory(\%dom, $parent); if (!$parent) { if (!$ginfo) { # Create the unix group print &text('setup_group', $crgroup),"
\n"; &foreign_call($usermodule, "lock_user_files"); %ginfo = ( 'group', $crgroup, 'gid', $gid ); &foreign_call($usermodule, "set_group_envs", \%ginfo, 'CREATE_GROUP'); &foreign_call($usermodule, "making_changes"); &foreign_call($usermodule, "create_group", \%ginfo); &foreign_call($usermodule, "unlock_user_files"); &foreign_call($usermodule, "made_changes"); print $text{'setup_done'},"

\n"; } else { %ginfo = %$ginfo; } if (!$uinfo) { # Create the Unix user # XXX use common function?? print &text('setup_user', $cruser),"
\n"; &foreign_call($usermodule, "lock_user_files"); %uinfo = ( 'user', $cruser, 'uid', $uid, 'gid', $gid, 'pass', &foreign_call($usermodule, "encrypt_password", $in{'pass'}), 'real', $owner, 'home', $dom{'home'}, 'shell', &default_available_shell('owner'), 'mailbox', $cruser, 'dom', $in{'dom'}, ); &set_pass_change(\%uinfo); &foreign_call($usermodule, "set_user_envs", \%uinfo, 'CREATE_USER', $in{'pass'}, [ ]); &foreign_call($usermodule, "making_changes"); &foreign_call($usermodule, "create_user", \%uinfo); &foreign_call($usermodule, "unlock_user_files"); &foreign_call($usermodule, "made_changes"); &foreign_call($usermodule, "unlock_user_files"); print $text{'setup_done'},"

\n"; if (!-d $uinfo{'home'}) { # Create his home directory, and copy files into it print $text{'setup_home'},"
\n"; &system_logged( "mkdir '$uinfo{'home'}'"); &system_logged( "chmod '$uconfig{'homedir_perms'}' '$uinfo{'home'}'"); &system_logged("chown $uid:$gid '$uinfo{'home'}'"); ©_skel_files($config{'virtual_skel'}, \%uinfo, $uinfo{'home'}); print $text{'setup_done'},"

\n"; } } else { %uinfo = %$uinfo; } } # Setup web directories print $text{'import_dirs'},"
\n"; foreach $d (&virtual_server_directories(\%dom)) { if (!-d "$uinfo{'home'}/$d->[0]") { &system_logged( "mkdir '$uinfo{'home'}/$d->[0]' 2>/dev/null"); &system_logged( "chmod $d->[1] '$uinfo{'home'}/$d->[0]'"); &system_logged( "chown $uid:$ugid '$uinfo{'home'}/$d->[0]'"); } } print $text{'setup_done'},"

\n"; if ($found{'ssl'}) { # Find and record the SSL key files &require_apache(); ($svirt, $svconf) = &get_apache_virtual($in{'dom'}, $default_web_sslport); $certfile = &apache::find_directive("SSLCertificateFile", $svconf); $keyfile = &apache::find_directive("SSLCertificateKeyFile", $svconf); $dom{'ssl_cert'} = $certfile; $dom{'ssl_key'} = $keyfile if ($keyfile); $dom{'web_sslport'} = $default_web_sslport; } # Find users matching regexp, and import them if (!$in{'regexp_def'}) { print &text('import_updating', "$in{'regexp'}"), "
\n"; $re = $in{'regexp'}; foreach $u (&list_all_users()) { next if ($u->{'user'} !~ /^$re$/); # If this user matches, change his primary group $oldu = { %$u }; $u->{'gid'} = $dom{'gid'}; &foreign_call($usermodule, "making_changes"); &foreign_call($usermodule, "lock_user_files"); &foreign_call($usermodule, "modify_user", $oldu, $u); &foreign_call($usermodule, "unlock_user_files"); &foreign_call($usermodule, "made_changes"); # Also fix group permissions on his home and mail file &useradmin::recursive_change($u->{'home'}, $u->{'uid'}, $oldu->{'gid'}, $u->{'uid'}, $u->{'gid'}); &useradmin::recursive_change(&user_mail_file($u), $u->{'uid'}, $oldu->{'gid'}, $u->{'uid'}, $u->{'gid'}); } print $text{'setup_done'},"

\n"; } # Create the domain details &complete_domain(\%dom); print $text{'setup_save'},"
\n"; &save_domain(\%dom, 1); print $text{'setup_done'},"

\n"; # Create or update webmin user if ($in{'webmin'} && !$parent) { &require_acl(); ($wuser) = grep { $_->{'name'} eq $cruser } &acl::list_users(); if ($wuser) { &modify_webmin(\%dom, \%dom); } else { &setup_webmin(\%dom); } } elsif ($parent) { # Update parent domain's webmin user &modify_webmin($parent, $parent); } &run_post_actions(); # Call any theme post command if (defined(&theme_post_save_domain)) { &theme_post_save_domain(\%dom, 'create'); } # Add to this user's list of domains if needed if (!&can_edit_domain(\%dom)) { $access{'domains'} = join(" ", split(/\s+/, $access{'domains'}), $dom{'id'}); &save_module_acl(\%access); } &webmin_log("import", "domain", $dom{'dom'}); } else { # Just work out what can be done print "$text{'import_idesc'}

\n"; # Work out the Unix username if (!$parent) { if ($in{'user_def'}) { # Creating a new user with a name taken from the domain $in{'dom'} =~ /^([^\.]+)/; $try1 = $user = $1; if (defined(getpwnam($1)) || $config{'longname'}) { $user = $in{'dom'}; $try2 = $user; if (defined(getpwnam($user))) { &error_exit(&text('setup_eauto', $try1,$try2)); } } print "",&text('import_user1', "$user"),"

\n"; } else { # Using a specified name, which may or may not exist if (defined(getpwnam($in{'user'}))) { print "",&text('import_user2', "$in{'user'}"),"

\n"; } else { print "",&text('import_user3', "$in{'user'}"),"

\n"; } } if ($in{'group_def'}) { # Need to create new group with the same name as user $group = $user || $in{'user'}; print "",&text('import_group1', "$group"),"

\n"; } elsif (scalar(@ginfo = getgrnam($in{'group'}))) { # Group already exists print "",&text('import_group2', "$in{'group'}"),"

\n"; $group = $in{'group'}; } else { # Group does not exist print "",&text('import_group3', "$in{'group'}"),"

\n"; } if (@ginfo) { # Find users in the group setpwent(); while(@muinfo = getpwent()) { $mcount++ if ($muinfo[3] == $ginfo[2]); } endpwent(); if ($mcount) { print "",&text('import_mailboxes', $mcount, "$in{'group'}"), "

\n"; } } if (!$in{'regexp_def'}) { # Find users who match regexp $re = $in{'regexp'}; setpwent(); while(@muinfo = getpwent()) { $rcount++ if ($muinfo[0] =~ /^$re$/); } endpwent(); if ($rcount) { print "",&text('import_mailboxes2', $rcount, "$in{'regexp'}"), "

\n"; } } } else { print "",&text('import_under', "$parent->{'dom'}"),"

\n"; } # Check for mail domain if ($config{'mail'}) { &require_mail(); $found{'mail'}++ if (&is_local_domain($in{'dom'})); if ($found{'mail'}) { print "",&text('import_mail', "$in{'dom'}"),"

\n"; } else { print &text('import_nomail', "$in{'dom'}"),"

\n"; } } # Check for an Apache virtualhost if ($config{'web'}) { &require_apache(); ($virt, $vconf) = &get_apache_virtual($in{'dom'}, $default_web_port); if ($virt) { $found{'web'}++; $sn = &apache::find_directive( "ServerName", $virt->{'members'}); $dr = &apache::find_directive( "DocumentRoot", $virt->{'members'}); print "",&text('import_web', "$sn", "$dr"),"

\n"; } else { print &text('import_noweb', "$in{'dom'}"),"

\n"; } } # Check for an SSL virtualhost if ($config{'ssl'}) { &require_apache(); ($svirt, $svconf) = &get_apache_virtual($in{'dom'}, $default_web_sslport); if ($svirt) { $found{'ssl'}++; $sn = &apache::find_directive( "ServerName", $svirt->{'members'}); $dr = &apache::find_directive( "DocumentRoot", $svirt->{'members'}); print "",&text('import_ssl', "$sn", "$dr"),"

\n"; } else { print &text('import_nossl', "$in{'dom'}"),"

\n"; } } # Check for Webalizer on the virtual host logs if ($config{'webalizer'}) { &require_webalizer(); $log = &get_apache_log($in{'dom'}); if ($log && -r &webalizer::config_file_name($log)) { $found{'webalizer'}++; print "",&text('import_webalizer', "$log"),"

\n"; } else { print &text('import_nowebalizer', "$log"),"

\n"; } } # Check for a DNS domain if ($config{'dns'}) { &require_bind(); $conf = &bind8::get_config(); @zones = &bind8::find("zone", $conf); foreach $v (&bind8::find("view", $conf)) { push(@zones, &bind8::find("zone", $v->{'members'})); } foreach $z (@zones) { if ($z->{'value'} eq $in{'dom'}) { $found{'dns'}++; last; } } if ($found{'dns'}) { print "",&text('import_dns', "$in{'dom'}"),"

\n"; } else { print &text('import_nodns', "$in{'dom'}"),"

\n"; } } # Check for databases @alldbs = &all_databases(); foreach $t ('mysql', 'postgres') { foreach $db (split(/\s+/, $in{'db_'.$t})) { local ($got) = grep { $_->{'type'} eq $t && $_->{'name'} eq $db } @alldbs; if ($got) { $found{$t}++; print "",&text('import_'.$t, "$db"),"

\n"; } else { print &text('import_no'.$t, "$db"),"

\n"; } push(@{$dbnames{$t}}, $db); } } # Check for a ProFTPd virtualhost if ($config{'ftp'} && $in{'virt'}) { &require_proftpd(); ($virt, $vconf, $anon, $aconf) = &get_proftpd_virtual($in{'ip'}); if ($virt && $anon) { $found{'ftp'}++; print "",&text('import_ftp', "$in{'ip'}", "$anon->{'value'}"),"

\n"; } elsif ($virt) { $found{'ftp'}++; print "",&text('import_ftpnoanon', "$in{'ip'}"),"

\n"; } else { print &text('import_noftp', "$in{'ip'}"),"

\n"; } } # Check for an existing logrotate configuration if ($config{'logrotate'}) { $log = &get_apache_log($in{'dom'}); $lconf = &get_logrotate_section($log); if ($log && $lconf) { $found{'logrotate'}++; print "",&text('import_logrotate', "$log"),"

\n"; } elsif ($log) { print &text('import_nologrotate', "$log"),"

\n"; } else { print &text('import_nologrotate2', "$in{'dom'}"),"

\n"; } } # Check for plugin features foreach $f (@feature_plugins) { $pname = &plugin_call($f, "feature_name"); if (&plugin_call($f, "feature_import", $in{'dom'}, $user || $in{'user'}, $in{'db'})) { $found{$f}++; print "",&text('import_plugin', $pname),"

\n"; } else { print &text('import_noplugin', $pname),"

\n"; } } if (!$parent) { # Tell if a Webmin user will be created if ($in{'webmin'}) { &require_acl(); ($wuser) = grep { $_->{'name'} eq ($user || $in{'user'}) } &acl::list_users(); if ($wuser) { print "",&text('import_webmin1', "$wuser->{'name'}"),"

\n"; } else { print "",&text('import_webmin2', "$wuser->{'name'}"),"

\n"; } } else { print "$text{'import_nowebmin'}

\n"; } } # Work out if IP would be assigned if ($in{'virt'}) { print "",&text('import_virt', "$iface->{'fullname'}"),"

\n"; } else { print "$text{'import_novirt'}

\n"; } # Output form with confirm button print &check_clicks_function(); print "

\n"; foreach $i (keys %in) { print "\n"; } foreach $f (keys %found) { print "\n"; } foreach $t (keys %dbnames) { print "\n"; } print "\n"; print "\n"; print "$text{'import_rusure'}

\n"; print "\n"; print "

\n"; } &ui_print_footer("", $text{'index_return'}); sub error_exit { print "",$text{'import_err'}," : ",@_,"

\n"; &ui_print_footer("", $text{'index_return'}); exit; }