#!/usr/bin/perl use lib qw(/usr/lib/libDrakX); # i18n: IMPORTANT: to get correct namespace (drakx-kbd-mouse-x11 and drak3d instead of libDrakX) BEGIN { unshift @::textdomains, 'drakx-net', 'drakx-kbd-mouse-x11', 'drak3d' } use standalone; $::isStandalone = 0; use common; use interactive; use any; use authentication; use network::network; use network::netconnect; use security::level; my $conf_file = '/etc/sysconfig/finish-install'; my %conf = getVarsFromSh($conf_file); my $authentication = authentication::get(); my $security = security::level::get(); my $net = {}; my $locale; network::network::read_net_conf($net); $::isWizard = 1; my $in = 'interactive'->vnew; sub ask_license() { any::acceptLicense($in); } sub ask_language() { require lang; $locale = lang::read(); any::selectLanguage_and_more_standalone($in, $locale); lang::write_and_install($locale, $in->do_pkgs); } sub ask_keyboard() { require keyboard; my $keyboard = $locale ? keyboard::lang2keyboard($locale->{lang}) : keyboard::read_or_default(); choose: $keyboard->{KEYBOARD} = $in->ask_from_listf(N("Keyboard"), N("Please, choose your keyboard layout."), sub { translate(keyboard::KEYBOARD2text($_[0])) }, [ keyboard::KEYBOARDs() ], $keyboard->{KEYBOARD}) or return; keyboard::group_toggle_choose($in, $keyboard) or goto choose; keyboard::configure_and_set_standalone($keyboard); } sub ask_timezone() { require timezone; my $t = timezone::read(); $t->{timezone} = timezone::bestTimezone($locale->{country}) if $locale->{country}; any::configure_timezone($in, $t, 'ask_gmt'); timezone::write($t); #- reload sys clock from hc once we know the real timezone timezone::reload_sys_clock($t); } sub ask_network() { my $modules_conf = modules::any_conf->read; require network::netconnect; network::netconnect::real_main($net, $in, $modules_conf); } sub ask_authentication() { my $meta_class = { getVarsFromSh("/etc/sysconfig/system") }->{META_CLASS}; my $superuser = {}; authentication::ask_root_password_and_authentication($in, $net, $superuser, $authentication, $meta_class, $security); authentication::set_root_passwd($superuser, $authentication); eval { authentication::set($in, $net, $authentication) or goto &ask_authentication; network::network::write_network_conf($net); }; if (my $err = $@) { $in->ask_warn(N("Error"), formatError($err)); goto &ask_authentication; } } sub ask_users() { my $users = []; any::ask_user($in, $users, $security); my $old_user = $conf{USER_RENAME_FROM}; my $old_autologin; if (@$users && $old_user) { $users->[0]{rename_from} = $old_user; $users->[0]{home} ||= '/home/' . $users->[0]{name}; } my $autologin = any::get_autologin(); $autologin_first = ($autologin->{autologin} eq $old_user || $conf{USER_AUTOLOGIN_FIRST} eq "yes") && $autologin->{desktop}; any::add_users($users, $authentication); any::set_autologin($in->do_pkgs, $users->[0]{name}, $autologin_first) if $autologin_first; } sub ask_glx() { require Xconfig::glx; my $glx = Xconfig::glx::detect_may_install($in); if ($glx->{supported} && Xconfig::glx::choose_interactive($in, $glx)) { Xconfig::glx::write($glx); } } sub ask_encrypt_home() { my $user = { name => $conf{ENCRYPT_HOME_USER}, device => $conf{ENCRYPT_HOME_DEVICE} }; any { !defined $_ } values %$user and return; $in->ask_from(N("Encrypted home partition"), N("Please enter a password for the %s user", $user->{name}), [ { label => N("Password"), val => \$user->{password}, hidden => 1 }, { label => N("Password (again)"), val => \$user->{password2}, hidden => 1 }, ], complete => sub { authentication::check_given_password($in, $user, 6) or return 1,0; return 0; }); authentication::write_passwd_user($user); encrypt_home($user); } sub encrypt_home { my ($user) = @_; my $device = $user->{device}; my $mapper = '/dev/mapper/' . $user->{name}; my $home = '/home/' . $user->{name}; my $wait = $in->wait_message(N("Encrypted home partition"), N("Creating encrypted home partition")); substInFile { s/^volume $user->{name}.*//; $_ .= "volume $user->{name} crypt - $device $home - - -\n" if eof; } $::prefix . '/etc/security/pam_mount.conf'; authentication::set_pam_authentication('mount'); run_program::raw({ root => $::prefix, sensitive_arguments => 1 }, "echo -e $user->{password} | cryptsetup luksFormat $device"); run_program::raw({ root => $::prefix, sensitive_arguments => 1 }, "echo -e $user->{password} | cryptsetup luksOpen $device $user->{name}"); $wait = $in->wait_message(N("Encrypted home partition"), N("Formatting encrypted home partition")); run_program::rooted($::prefix, 'mke2fs', '-qj', '-m', 0, '-L', 'Home', $mapper); my $old_home; if (-d $::prefix . $home) { #- if already existing, move home to a temporary folder require File::Temp; $old_home = File::Temp::tempdir(DIR => dirname($::prefix . $home)); rmdir $old_home; rename $::prefix . $home, $old_home; } mkdir_p($::prefix . $home); run_program::rooted($::prefix, 'mount', $mapper, $home); if ($old_home) { #- copy previous home back require File::Copy::Recursive; File::Copy::Recursive::dirmove($old_home, $::prefix . $home); } run_program::rooted($::prefix, 'chown', '-R', join(':', ($user->{name}) x 2), $home); rmdir $::prefix . $home . '/lost+found'; run_program::rooted($::prefix, 'umount', $home); run_program::rooted($::prefix, 'cryptsetup', 'luksClose', $user->{name}); } sub call { my ($step_name) = @_; my $f_name = 'ask_' . $step_name; if (member('no', map { lc($conf{$_}) } lc($step_name), uc($step_name))) { log::l("ignoring $f_name"); } else { log::l("calling $f_name"); my $f = $::{$f_name} or internal_error "bad function $f_name"; eval { $f->() }; log::l("$f_name failed: $@") if $@; } } call('language'); call('license'); # "Previous" button isn't functiunnal and acts like "next" (#25349) $::Wizard_no_previous = 1; call('keyboard'); call('timezone'); call('network'); if (defined $::WizardWindow) { $::WizardWindow->destroy; undef $::WizardWindow; } $::Wizard_pix_up = 'redhat-config-users'; call('authentication'); call('users'); call('encrypt_home'); call('glx'); setVarsInSh($conf_file, { FINISH_INSTALL => 'no' }); $in->exit(0);