#!/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"; &ui_print_footer("", $text{'index_return'}); exit; }