diff options
Diffstat (limited to 'perl-install/standalone/drakTermServ')
-rwxr-xr-x | perl-install/standalone/drakTermServ | 2198 |
1 files changed, 0 insertions, 2198 deletions
diff --git a/perl-install/standalone/drakTermServ b/perl-install/standalone/drakTermServ deleted file mode 100755 index eff413cd9..000000000 --- a/perl-install/standalone/drakTermServ +++ /dev/null @@ -1,2198 +0,0 @@ -#!/usr/bin/perl -# -# Copyright (C) 2002-2005 by Mandriva (sbenedict@mandrakesoft.com) -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -use lib qw(/usr/lib/libDrakX); - -use standalone; #- warning, standalone must be loaded very first, for 'explanations' -use strict; - -use interactive; -use ugtk2 qw(:helpers :wrappers :create); -use common; -use run_program; -use bootloader; -use network::pxe; - -use Config; -use POSIX; - -my $in = 'interactive'->vnew('su'); - -my @buff; #- used to display status info - -my $central_widget; -my $window1; -my $status_box; -my $main_box; -my $wizard_buttons; -my $previous_button; -my $cancel_button; -my $next_button; -my $main_buttons; -my $progress; -my $plabel; -my $in_wizard = 0; -my $config_written = 0; -my $clients_set = 0; -my @nothing = (0..10); -my %conf; -$conf{ALLOW_THIN} = 0; -$conf{CREATE_PXE} = 0; - -my $nfs_subnet; -my $nfs_mask; -my $cfg_dir = "/etc/drakxtools/draktermserv/"; --e $cfg_dir or mkdir_p($cfg_dir); -my $cfg_file = $cfg_dir . "draktermserv.conf"; -my $interface = get_net_interface(); -my $server_ip = get_ip_from_sys(); -my $changes_made = 0; -my $client_cfg = "/etc/dhcpd.conf.etherboot.clients"; -my $tftpboot = "/var/lib/tftpboot"; -my @kernels = bootloader::installed_vmlinuz(); -my $kcount = @kernels; -my $cmd_line = 1; -my $mknbi = "/usr/bin/mknbi-set"; -my %help; -our $ts_prefix = "/var/lib/terminal-server/"; -our $client_prefix = $ts_prefix . "clients"; -our $common_prefix = $ts_prefix . "common"; - -read_conf_file(); -my $nfs_daemon = $conf{USE_UNIONFS} ? "nfs" : "clusternfs"; -my $ts_package = $conf{USE_UNIONFS} ? "terminal-server2" : "terminal-server"; - -#- make sure terminal server and friends are installed -$in->do_pkgs->ensure_is_installed($ts_package, '/usr/bin/drakTermServ') or $in->exit(-1); - -my $argc = @ARGV; - -if ("@ARGV" =~ /--enable/) { - enable_ts(); - exit(0); -} - -if ("@ARGV" =~ /--disable/) { - disable_ts(); - exit(0); -} - -if ("@ARGV" =~ /--restart/) { - stop_ts(); - start_ts(); - exit(0); -} - -if ("@ARGV" =~ /--start/) { - start_ts(); - exit(0); -} - -if ("@ARGV" =~ /--stop/) { - stop_ts(); - exit(0); -} - -if ("@ARGV" =~ /--adduser/) { - die N("%s: %s requires a username...\n", $0, $ARGV[0]) if $argc < 2; - adduser($ARGV[1]); - exit(0); -} - -if ("@ARGV" =~ /--deluser/) { - die N("%s: %s requires a username...\n", $0, $ARGV[0]) if $argc < 2; - deluser($ARGV[1]); - exit(0); -} - -if ("@ARGV" =~ /--syncusers/) { - sync_users(); - exit(0); -} - -if ("@ARGV" =~ /--addclient/) { - die N("%s: %s requires hostname, MAC address, IP, nbi-image, 0/1 for THIN_CLIENT, 0/1 for Local Config...\n", $0, $ARGV[0]) if $argc < 7; - addclient(@ARGV[1..6]); - exit(0); -} - -if ("@ARGV" =~ /--delclient/) { - die N("%s: %s requires hostname...\n", $0, $ARGV[0]) if $argc < 2; - delclient($ARGV[1]); - exit(0); -} - -interactive_mode() if $argc < 2; - -sub setup_tooltips() { - %help = ( - 'client_name' => N("Host name for client"), - 'mac_address' => N("MAC address should be in the format 00:11:22:33:44:55"), - 'ip_address' => N("IP address to be assigned to client"), - 'netboot_image' => N("Kernel/network adapter image to use to boot client"), - 'local_hardware' => N("Create masking files to allow configuration tools to run on client"), - 'thin_client' => N("Applications will run on server machine"), - ); -} - -sub set_help_tip { - my ($entry, $key) = @_; - gtkset_tip(Gtk2::Tooltips->new, $entry, formatAlaTeX($help{$key})); -} - -sub read_conf_file() { - if (-e $cfg_file) { - substInFile { s/ALLOW_THIN$/ALLOW_THIN=1/ } $cfg_file; - %conf = getVarsFromSh($cfg_file); - } -} - -sub write_conf_file() { - setVarsInSh($cfg_file, \%conf); - chmod(0600, $cfg_file); -} - -sub write_thin_inittab { - my ($client_ip) = @_; - my $suffix; - my $prefix = $conf{USE_UNIONFS} ? "$client_prefix/$client_ip" : ''; - if ($client_ip eq "CLIENT") { - $suffix = '$$CLIENT$$'; - } else { - $suffix = "\$\$IP=$client_ip\$\$"; - } - $suffix = '' if $conf{USE_UNIONFS}; - - my $inittab = " -# /etc/inittab$suffix -# created by drakTermServ - -id:5:initdefault: - -# System initialization. -si::sysinit:/etc/rc.d/rc.sysinit - -l0:0:wait:/etc/rc.d/rc 0 -l1:1:wait:/etc/rc.d/rc 1 -l2:2:wait:/etc/rc.d/rc 2 -l3:3:wait:/etc/rc.d/rc 3 -l4:4:wait:/etc/rc.d/rc 4 -l5:5:wait:/etc/rc.d/rc 5 -l6:6:wait:/etc/rc.d/rc 6 - -# Things to run in every runlevel. -ud::once:/sbin/update - -# Trap CTRL-ALT-DELETE -ca::ctrlaltdel:/sbin/reboot -f - -# Run gettys in standard runlevels -1:2345:respawn:/sbin/mingetty tty1 - -# Connect to X server -x:5:respawn:/usr/X11R6/bin/X -ac -query $server_ip\n"; - - my $inittab_file = "$prefix/etc/inittab$suffix"; - output_p($inittab_file, $inittab); -} - -sub display_error { - my ($message) = @_; - my $error_box; - destroy_widget(); - gtkpack($status_box, - $error_box = gtkpack_(Gtk2::VBox->new(0,0), - 1, Gtk2::Label->new($message), - 0, gtkadd(gtkset_layout(Gtk2::HButtonBox->new, 'spread'), - gtksignal_connect(Gtk2::Button->new(N("Ok")), clicked => sub { - destroy_widget(); - }), - ), - ) - ); - $central_widget = \$error_box; -} - -sub interactive_mode() { - $cmd_line = 0; - $in = 'interactive'->vnew; - $::Wizard_title = N("Terminal Server Configuration"); - $::Wizard_pix_up = "ic82-network-40.png"; - $in->isa('interactive::gtk') and $::isWizard = 0; - $window1 = ugtk2->new(N("Terminal Server Configuration")); - $window1->{rwindow}->signal_connect(delete_event => sub { ugtk2->exit(0) }); - $window1->{rwindow}->set_border_width(5); - - my $s_buttons = Gtk2::HBox->new; - gtkpack_($s_buttons, - 1, gtksignal_connect(Gtk2::Button->new(N("dhcpd Config")), clicked => sub { - destroy_widget(); - dhcpd_config(); - }), - 1, gtksignal_connect(Gtk2::Button->new(N("Enable Server")), clicked => sub { - destroy_widget(); - gtkset_mousecursor_wait(); - enable_ts(); - gtkset_mousecursor_normal(); - }), - 1, gtksignal_connect(Gtk2::Button->new(N("Disable Server")), clicked => sub { - destroy_widget(); - gtkset_mousecursor_wait(); - disable_ts(); - gtkset_mousecursor_normal(); - }), - 1, gtksignal_connect(Gtk2::Button->new(N("Start Server")), clicked => sub { - destroy_widget(); - gtkset_mousecursor_wait(); - start_ts(); - gtkset_mousecursor_normal(); - }), - 1, gtksignal_connect(Gtk2::Button->new(N("Stop Server")), clicked => sub { - destroy_widget(); - gtkset_mousecursor_wait(); - stop_ts(); - gtkset_mousecursor_normal(); - }), - ); - my $i_buttons = Gtk2::HBox->new; - gtkpack_($i_buttons, - 1, gtksignal_connect(Gtk2::Button->new(N("Etherboot Floppy/ISO")), clicked => sub { - destroy_widget(); - make_boot(); - }), - 1, gtksignal_connect(Gtk2::Button->new(N("Net Boot Images")), clicked => sub { - destroy_widget(); - make_nbi(); - }), - ); - my $c_buttons = Gtk2::HBox->new; - gtkpack_($c_buttons, - 1, gtksignal_connect(Gtk2::Button->new(N("Add/Del Users")), clicked => sub { - destroy_widget(); - maintain_users(); - }), - 1, gtksignal_connect(Gtk2::Button->new(N("Add/Del Clients")), clicked => sub { - destroy_widget(); - maintain_clients(); - }), - ); - - $main_buttons = Gtk2::Notebook->new; - $main_buttons->append_page($s_buttons, gtkshow(Gtk2::Label->new(N("Server")))); - $main_buttons->append_page($i_buttons, gtkshow(Gtk2::Label->new(N("Images")))); - $main_buttons->append_page($c_buttons, gtkshow(Gtk2::Label->new(N("Clients/Users")))); - $main_buttons->set_show_border(0); - $main_buttons->set_tab_pos('bottom'); - gtkadd($window1->{window}, - gtkpack_(gtkset_size_request(Gtk2::VBox->new(0,2), 620, 400), - 1, gtkpack_(Gtk2::HBox->new(0,2), - 1, gtkpack_(Gtk2::VBox->new(0,2), - 1, gtkpack($status_box = Gtk2::VBox->new(0,5), - $main_box = Gtk2::VBox->new(0,10), - ), - 0, $wizard_buttons = gtkpack_(Gtk2::HBox->new(1,2)), - 0, $main_buttons, - 0, gtkpack_(Gtk2::HBox->new, - 0, gtksignal_connect(Gtk2::Button->new(N("Help")),clicked => sub { - destroy_widget(); - help(); - }), - 1, "", - 0, gtksignal_connect(Gtk2::Button->new(N("First Time Wizard")), clicked => sub { - destroy_widget(); - start_wizard(); - }), - 1, "", - 0, gtksignal_connect(Gtk2::Button->new(N("Close")), clicked => sub { - write_conf_file(); - restart_server() if $changes_made == 1; - Gtk2->main_quit; - }), - ), - ), - ), - ), - ); - setup_tooltips(); - $central_widget = \$main_box; - $window1->{rwindow}->show_all; - $window1->{rwindow}->realize; - $window1->{rwindow}->show_all; - #- strange behavior with tabs, pressing a button actually ends up - #- activating a hidden button below it - $main_buttons->set_current_page(2); - $main_buttons->set_current_page(1); - $main_buttons->set_current_page(0); - gtksignal_connect($main_buttons, switch_page => sub { destroy_widget() }); - gtkflush(); - $window1->main; - ugtk2->exit(0); -} - -sub check_gdm() { - #- gdm now needs gdm user in /etc/passwd$$CLIENT$$ - my %desktop = getVarsFromSh("/etc/sysconfig/desktop"); - my $dm = $desktop{DISPLAYMANAGER}; - $dm =~ tr/a-z/A-Z/; - my $gdm = `grep gdm '/etc/passwd\$\$CLIENT\$\$'`; - if ($dm =~ /GNOME|GDM/ && !$gdm) { - $in->ask_warn(N("Warning"), N("%s defined as dm, adding gdm user to /etc/passwd\$\$CLIENT\$\$", $dm)) if !$cmd_line; - warn(N("%s defined as dm, adding gdm user to /etc/passwd\$\$CLIENT\$\$", $dm)) if $cmd_line; - adduser("gdm"); - } -} - -sub start_wizard() { - text_view(N(" - This wizard routine will: - 1) Ask you to select either 'thin' or 'fat' clients. - 2) Setup DHCP. - -After doing these steps, the wizard will: - - a) Make all nbis. - b) Activate the server. - c) Start the server. - d) Synchronize the shadow files so that all users, including root, - are added to the shadow\$\$CLIENT\$\$ file. - e) Ask you to make a boot floppy. - f) If it's thin clients, ask if you want to restart KDM. -"), "wizard"); -} - -sub do_wizard() { - destroy_widget(); - $main_buttons->hide; - $in_wizard = 1; - $config_written = 0; - %conf = ''; - wizard_step(\&client_type, 1); -} - -sub wizard_step { - my ($do_step, $step) = @_; - &$do_step(); - gtkadd($wizard_buttons, - gtksignal_connect($previous_button = Gtk2::Button->new(N("Previous")), clicked => sub { - clear_buttons(); - if ($step == 1) { - exit_wizard(); - start_wizard(); - } - wizard_step(\&client_type, 1) if $step == 2; - wizard_step(\&dhcpd_config, 2) if $step == 3; - wizard_step(\&make_nbis, 3) if $step == 4; - wizard_step(\&enable_ts, 4) if $step == 5; - wizard_step(\&restart_ts, 5) if $step == 6; - wizard_step(\&sync_users, 6) if $step == 7; - wizard_step(\&make_boot, 7) if $step == 8; - }) - ); - gtkadd($wizard_buttons, - gtksignal_connect($cancel_button = Gtk2::Button->new(N("Cancel Wizard")), clicked => sub { - exit_wizard(); - }) - ); - gtkadd($wizard_buttons, - gtksignal_connect($next_button = Gtk2::Button->new(N("Next")), clicked => sub { - clear_buttons(); - if ($step == 1) { - client_X_keyboard() if $conf{SYNC_KBD}; - wizard_step(\&dhcpd_config, 2); - } - if ($step == 2) { - if ($config_written == 1) { - wizard_step(\&make_nbis, 3); - } else { - $in->ask_warn(N("Error"), N("Please save dhcpd config!")); - wizard_step(\&dhcpd_config, 2); - } - } - wizard_step(\&enable_ts, 4) if $step == 3; - wizard_step(\&restart_ts, 5) if $step == 4; - wizard_step(\&sync_users, 6) if $step == 5; - wizard_step(\&make_boot, 7) if $step == 6; - wizard_step(\&restart_dm, 8) if $step == 7; - }) - ); - exit_wizard() if $step == 8; -} - -sub exit_wizard() { - clear_buttons(); - $in_wizard = 0; - $main_buttons->show; -} - -sub clear_buttons() { - destroy_widget(); - $previous_button->destroy; - $cancel_button->destroy; - $next_button->destroy; -} - -sub client_type() { - my $check_allow_thin = Gtk2::CheckButton->new(N("Use thin clients.")); - $check_allow_thin->set_active($conf{ALLOW_THIN}); - my $check_sync_kbd = Gtk2::CheckButton->new(N("Sync client X keyboard settings with server.")); - $check_sync_kbd->set_active($conf{SYNC_KBD}); - text_view(N("Please select default client type (Fat is the default type if 'Use thin' is unchecked). - 'Thin' clients run everything off the server's CPU/RAM, using the client display. - 'Fat' clients use their own CPU/RAM but the server's filesystem."), "wizard"); - gtkpack_($$central_widget, - 0, gtkpack_(Gtk2::HBox->new(0,0), - 1, Gtk2::VBox->new, - 0, gtksignal_connect($check_allow_thin, clicked => sub { - invbool \$conf{ALLOW_THIN}; - client_set("all"); - }), - 0, gtksignal_connect($check_sync_kbd, clicked => sub { - invbool \$conf{SYNC_KBD}; - }), - 1, Gtk2::VBox->new, - ), - 0, Gtk2::VBox->new, - ); -} - -sub make_nbis() { - my $buff = N("Creating net boot images for all kernels"); - $in->ask_warn(N("Information"), N("This will take a few minutes.")); - if (check_nbi_space($kernels[0], $kcount)) { - $wizard_buttons->hide; - exit_wizard(); - } else { - build_w_progress(undef, undef); - $buff .= "\n\n\t" . N("Done!"); - text_view($buff, "wizard"); - } -} - -sub check_nbi_space { - my ($kernel, $kcount) = @_; - log::explanations("Checking for adequate free space to create NBIs for $kcount kernel(s)"); - my $nbi_count = `$mknbi -c -k /boot/$kernel`; - chomp $nbi_count; - if ($nbi_count eq '') { - $in->ask_warn(N("Error"), N("%s failed", $mknbi)); - return 1; - } - my $needed_space = $nbi_count * $kcount * 2; - my $free = `df -P $tftpboot | tail -1`; - my @line_data = split(/[ \t,]+/, $free); - #- don't use more than 80% - my $free_space = int($line_data[3] / 1024); - if ($needed_space > $free_space * 0.8) { - $in->ask_warn(N("Error"), N("Not enough space to create\nNBIs in %s.\nNeeded: %d MB, Free: %d MB", $tftpboot, $needed_space, $free_space)); - return 1; - } -} - -sub sync_users() { - my $buff = N("Syncing server user list with client list, including root."); - my @active_users = cat_("/etc/shadow"); - - my ($shadow, undef) = get_passwd_files(); - my @userlist; - - #- only users with home dirs, and root - foreach my $user (@active_users) { - my @fields = split(/:/, $user); - if (-d "/home/" . $fields[0] || $fields[0] eq "root") { - push @userlist, $user; - } - } - output_p($shadow, @userlist); - $buff .= "\n\n\t" . N("Done!"); - text_view($buff, "wizard") if !$cmd_line; -} - -sub restart_dm() { - if ($clients_set) { - my $result = $in->ask_okcancel('', N("In order to enable changes made for thin clients, the display manager must be restarted. Restart now?")); - run_program::run('nohup /sbin/service dm restart') if $result; - } -} - -sub text_view { - my ($text, $option) = @_; - my $box; - gtkpack($status_box, - $box = gtkpack_(Gtk2::VBox->new(0,10), - 1, gtkpack_(Gtk2::HBox->new(0,0), - 1, create_scrolled_window(gtktext_insert( - Gtk2::TextView->new, [ [ $text ] ]) - ), - ), - 0, gtkpack(gtkset_layout(Gtk2::HButtonBox->new, 'spread'), - gtksignal_connect(my $ok_button = Gtk2::Button->new(N("Ok")), clicked => sub { - destroy_widget() if $option eq "close"; - do_wizard() if $option eq "wizard"; - }), - ), - ) - ); - gtkset_size_request($box, 580, 280); - $central_widget = \$box; - $status_box->show_all; - $ok_button->hide if $in_wizard; - $main_buttons->hide if $in_wizard; -} - -sub help() { - my $inittab_str = $conf{USE_UNIONFS} ? "$client_prefix/CLIENT_IP/etc/inittab" : '/etc/inittab$$IP=client_ip$$'; - my ($shadow_str, undef) = get_passwd_files(); - my $xfconfig_str = $conf{USE_UNIONFS} ? "$client_prefix/CLIENT_IP/etc/X11/xorg.conf" : '/etc/X11/xorg.conf$$IP=client_ip$$'; - my $filesystem = $conf{USE_UNIONFS} ? "UnionFS" : "ClusterNFS"; - my $application = "drakTermServ"; - - text_view(N("Terminal Server Overview") . "\n\n" . -N(" - Create Etherboot Enabled Boot Images: - To boot a kernel via etherboot, a special kernel/initrd image must be created. - mkinitrd-net does much of this work and %s is just a graphical - interface to help manage/customize these images. To create the file - /etc/dhcpd.conf.etherboot-pcimap.include that is pulled in as an include in - dhcpd.conf, you should create the etherboot images for at least one full kernel.", $application) . "\n\n" . -N(" - Maintain /etc/dhcpd.conf: - To net boot clients, each client needs a dhcpd.conf entry, assigning an IP - address and net boot images to the machine. %s helps create/remove - these entries. - - (PCI cards may omit the image - etherboot will request the correct image. - You should also consider that when etherboot looks for the images, it expects - names like boot-3c59x.nbi, rather than boot-3c59x.2.4.19-16mdk.nbi). - - A typical dhcpd.conf stanza to support a diskless client looks like:", $application) . "\n\n" . -' host curly { - hardware ethernet 00:20:af:2f:f7:9d; - fixed-address 192.168.192.3; - #type fat; - filename "i386/boot/boot-3c509.2.4.18-6mdk.nbi"; - #hdw_config true; - } - ' . "\n" . -N(" While you can use a pool of IP addresses, rather than setup a specific entry for - a client machine, using a fixed address scheme facilitates using the functionality - of client-specific configuration files that %s provides. - - Note: The '#type' entry is only used by %s. Clients can either be 'thin' - or 'fat'. Thin clients run most software on the server via XDMCP, while fat clients run - most software on the client machine. A special inittab, - %s is written for thin clients. - System config files xdm-config, kdmrc, and gdm.conf are modified if thin clients are - used, to enable XDMCP. Since there are security issues in using XDMCP, hosts.deny and - hosts.allow are modified to limit access to the local subnet. - - Note: The '#hdw_config' entry is also only used by %s. Clients can either - be 'true' or 'false'. 'true' enables root login at the client machine and allows local - hardware configuration of sound, mouse, and X, using the 'drak' tools. This is enabled - by creating separate config files associated with the client's IP address and creating - read/write mount points to allow the client to alter the file. Once you are satisfied - with the configuration, you can remove root login privileges from the client. - - Note: You must stop/start the server after adding or changing clients.", $filesystem, $application, $inittab_str, $application) . "\n\n" . -N(" - Maintain /etc/exports: - %s allows export of the root filesystem to diskless clients. %s - sets up the correct entry to allow anonymous access to the root filesystem from - diskless clients. - - A typical exports entry for %s is: - - / (ro,all_squash) - /home SUBNET/MASK(rw,root_squash) - - With SUBNET/MASK being defined for your network.", $filesystem, $application, $filesystem) . - "\n\n" . -N(" - Maintain %s: - For users to be able to log into the system from a diskless client, their entry in - /etc/shadow needs to be duplicated in %s. - %s helps in this respect by adding or removing system users from this - file.", $shadow_str, $shadow_str, $application) . "\n\n" . -N(" - Per client %s: - Through %s, each diskless client can have its own unique configuration files - on the root filesystem of the server. By allowing local client hardware configuration, - %s will help create these files.", $xfconfig_str, $filesystem, $application) . -"\n\n" . -N(" - Per client system configuration files: - Through %s, each diskless client can have its own unique configuration files - on the root filesystem of the server. By allowing local client hardware configuration, - clients can customize files such as /etc/modules.conf, /etc/sysconfig/mouse, - /etc/sysconfig/keyboard on a per-client basis. - - Note: Enabling local client hardware configuration does enable root login to the terminal - server on each client machine that has this feature enabled. Local configuration can be - turned back off, retaining the configuration files, once the client machine is configured.", $filesystem) . "\n\n" . -N(" - /etc/xinetd.d/tftp: - %s will configure this file to work in conjunction with the images created - by mkinitrd-net, and the entries in /etc/dhcpd.conf, to serve up the boot image to - each diskless client. - - A typical TFTP configuration file looks like: - - service tftp - { - disable = no - socket_type = dgram - protocol = udp - wait = yes - user = root - server = /usr/sbin/in.tftpd - server_args = -s /var/lib/tftpboot - } - - The changes here from the default installation are changing the disable flag to - 'no' and changing the directory path to /var/lib/tftpboot, where mkinitrd-net - puts its images.", $application) . "\n\n" . -N(" - Create etherboot floppies/CDs: - The diskless client machines need either ROM images on the NIC, or a boot floppy - or CD to initiate the boot sequence. %s will help generate these - images, based on the NIC in the client machine. - - A basic example of creating a boot floppy for a 3Com 3c509 manually: - - cat /usr/share/etherboot/zdsk/3c509.zdsk > /dev/fd0", $application) . "\n\n", "close"); -} - -sub make_boot() { - #- make a boot image on floppy or iso from etherboot images - my $boot_box; - my $rom_path = "/usr/share/etherboot"; - #- does not return list sorted - my @nics = sort(all("/usr/share/etherboot/zdsk")); - my $list_nics = Gtk2::List->new; - my $nic; - - foreach (@nics) { - my $t = $_; - $list_nics->add(gtkshow(gtksignal_connect(Gtk2::ListItem->new($t), - select => sub { $nic = $t }))); - } - $list_nics->set_selection_mode('single'); - - gtkpack($status_box, - $boot_box = gtkpack_(Gtk2::VBox->new(0,10), - 0, gtkadd(Gtk2::HBox->new(0,10), - Gtk2::HBox->new(0,5), - create_scrolled_window($list_nics), - gtkadd(Gtk2::VBox->new(1,10), - Gtk2::HBox->new(0,20), - gtksignal_connect(Gtk2::Button->new(N("Boot Floppy")), clicked => - sub { write_eb_image($nic, $rom_path, "floppy") }), - gtksignal_connect(Gtk2::Button->new(N("Boot ISO")), clicked => - sub { write_eb_image($nic, $rom_path, "iso") }), - gtksignal_connect(Gtk2::Button->new(N("PXE Image")), clicked => - sub { write_eb_image($nic, $rom_path, "pxe") }), - Gtk2::HBox->new(0,20), - ), - Gtk2::HBox->new(0,5), - ), - ), - ); - - $central_widget = \$boot_box; - $boot_box->show_all; -} - -sub make_nbi() { - my $nbi_box; - my $kernel; - my $nic; - - require list_modules; - my @nics = sort(list_modules::category2modules(list_modules::ethernet_categories())); - - #- kernel/module info in tree view - my $model = Gtk2::TreeStore->new("Glib::String"); - my $tree_kernels = Gtk2::TreeView->new_with_model($model); - $tree_kernels->append_column(Gtk2::TreeViewColumn->new_with_attributes(undef, Gtk2::CellRendererText->new, 'text' => 0)); - $tree_kernels->set_headers_visible(0); - $tree_kernels->get_selection->set_mode('single'); - - foreach (@kernels) { - my $t_kernel = $model->append_set(undef, [ 0 => $_ ]); - foreach (@nics) { - $model->append_set($t_kernel, [ 0 => $_ ]); - } - } - - $tree_kernels->get_selection->signal_connect(changed => sub { - $kernel = ''; - $nic = ''; - my ($model, $iter) = $_[0]->get_selected; - $model && $iter or return; - my $value = $model->get($iter, 0); - my $path = $model->get_path_str($iter); - if ($path !~ /:/) { - $kernel = $value; - } else { - my @elements = split(/:/, $path); - $nic = $value; - $kernel = $kernels[$elements[0]]; - } - }); - - # existing nbi images in list - my $list_model = Gtk2::ListStore->new("Glib::String"); - my $list_nbis = Gtk2::TreeView->new_with_model($list_model); - $list_nbis->append_column(Gtk2::TreeViewColumn->new_with_attributes(undef, Gtk2::CellRendererText->new, 'text' => 0)); - $list_nbis->set_headers_visible(0); - my $nbi; - my $nbi_iter; - - update_list($list_model); - - my $combo_default_kernel = Gtk2::ComboBox->new_with_strings([ N("Default kernel version"), - map { bootloader::vmlinuz2version($_) } @kernels ]); - - my $entry_kargs = Gtk2::Entry->new; - $entry_kargs->set_width_chars(12); - my $check_pxe = Gtk2::CheckButton->new(N("Create PXE images")); - my $check_union = Gtk2::CheckButton->new(N("Use Unionfs (TS2)")); - #- disable until kernel support appears - $check_union->set_sensitive(0); - $check_pxe->set_active($conf{CREATE_PXE}); - $check_pxe->signal_connect('clicked' => sub { invbool \$conf{CREATE_PXE} }); - $check_union->set_active($conf{USE_UNIONFS}); - $check_union->signal_connect('clicked' => sub { invbool \$conf{USE_UNIONFS} }); - - $combo_default_kernel->set_active(0); - $combo_default_kernel->entry->signal_connect('changed', sub { - my $default_kernel = $combo_default_kernel->entry->get_text; - my $config; - if ($default_kernel eq translate("Default kernel version")) { - $config = ""; - } else { - $config = 'option bootfile-name = pick-first-value ( concat ( "boot-",' . "\n"; - $config .= ' config-option etherboot.kmod, ".' . $default_kernel . '", ".nbi" ), concat' . "\n"; - $config .= ' ( "boot-", config-option etherboot.kmod, ".nbi") ,"boot.nbi" );' . "\n"; - } - output_p("/etc/dhcpd.conf.etherboot.kernel", $config); - }); - - $list_nbis->get_selection->signal_connect(changed => sub { - my ($model, $iter) = $_[0]->get_selected; - $model && $iter or return; - $nbi = $model->get($iter, 0); - $nbi_iter = $iter; - }); - my $button_i586_kernel; - if (arch() eq "i686" && !(any { /i586/ } @kernels)) { - $button_i586_kernel = Gtk2::Button->new(N("Install i586 kernel for older clients")); - gtksignal_connect($button_i586_kernel, clicked => sub { - $in->do_pkgs->install('kernel-i586-up-1GB-2.6'); - }); - } - gtkpack($status_box, - $nbi_box = gtkpack_(Gtk2::VBox->new(1,10), - 0, gtkadd(Gtk2::HBox->new(1,5), - create_scrolled_window($tree_kernels), - gtkadd(Gtk2::VBox->new(0,5), - gtksignal_connect(Gtk2::Button->new(N("Build Whole Kernel -->")), clicked => sub { - if ($kernel) { - $in->ask_warn(N("Information"), N("This will take a few minutes.")); - gtkset_mousecursor_wait(); - build_n_update($kernel, $list_model, undef, $entry_kargs->get_text) unless check_nbi_space($kernel, 1); - gtkset_mousecursor_normal(); - } else { - $in->ask_warn(N("Error"), N("No kernel selected!")) if !($kernel); - } - }), - gtksignal_connect(Gtk2::Button->new(N("Build Single NIC -->")), clicked => sub { - if ($nic) { - build_n_update($kernel, $list_model, $nic, $entry_kargs->get_text); - } else { - $in->ask_warn(N("Error"), N("No NIC selected!")); - } - }), - gtksignal_connect(Gtk2::Button->new(N("Build All Kernels -->")), clicked => sub { - $in->ask_warn(N("Information"), N("This will take a few minutes.")); - my $kcount = @kernels; - if (check_nbi_space($kernels[0], $kcount)) { - return; - } else { - build_w_progress($list_model, undef, $entry_kargs->get_text); - make_nbi(); - } - }), - $button_i586_kernel, - $combo_default_kernel, - gtkadd(Gtk2::HBox->new(0,5), - Gtk2::Label->new(N("Custom\nkernel args")), - $entry_kargs, - ), - $check_pxe, - $check_union, - gtksignal_connect(Gtk2::Button->new(N("<-- Delete")), clicked => sub { - if ($nbi) { - my $result = clear_nbi($nbi); - $list_model->remove($nbi_iter) if $result == 1; - } else { - $in->ask_warn(N("Error"), N("No image selected!")); - } - }), - gtksignal_connect(Gtk2::Button->new(N("Delete All NBIs")), clicked => sub { - gtkset_mousecursor_wait(); - foreach (grep { /\.nbi/ } all($tftpboot)) { - clear_nbi($_); - } - $list_model->clear; - gtkset_mousecursor_normal(); - }), - ), - create_scrolled_window($list_nbis), - ),), - ); - - $central_widget = \$nbi_box; - $nbi_box->show_all; -} - -sub clear_nbi { - my ($nbi) = @_; - $nbi = $tftpboot . "/" . $nbi; - my $result = unlink($nbi) or warn("Can not delete $nbi..."); - $nbi =~ s|boot-|initrd-|; - $nbi =~ s|nbi|img|; - unlink($nbi); - if ($conf{CREATE_PXE}) { - my $pxe = get_platform_pxe(); - $nbi =~ s|$tftpboot/|$pxe|; - unlink($nbi); - del_pxe_entry($nbi) if -d $pxe; - } - return $result; -} - -sub update_list { - my ($list_model) = @_; - $list_model->clear; - $list_model->append_set(0, $_) foreach grep { /\.nbi/ } sort(all($tftpboot)); -} - -sub build_n_update { - my ($kernel, $list_model, $nic, @kargs) = @_; - my $xtra_args = join(" ", @kargs); - my $command = "-k /boot/$kernel"; - $command .= " -r $nic" if $nic; - $command .= " -u" if $conf{USE_UNIONFS}; - $command .= " -a '" . $xtra_args . "'" if length($xtra_args); - run_program::run("$mknbi -v $command") or $in->ask_warn(N("Error"), N("%s failed", $mknbi)); - if ($conf{CREATE_PXE}) { - my $pxedir = get_platform_pxe(); - if (-d $pxedir) { - cp_af("/boot/$kernel", $pxedir) if !-f "$pxedir/$kernel"; - link_pxe($kernel, $nic); - add_pxe_entry($kernel, $nic); - } - } - update_list($list_model) if $list_model; -} - -sub build_w_progress { - my ($widget, $nic, @kargs) = @_; - gtkset_mousecursor_wait(); - show_progress(); - my $k = 1; - foreach (@kernels) { - build_n_update($_, $widget, $nic, @kargs); - update_progress($k, $kcount, $_); - $k++; - } - destroy_widget(); - gtkset_mousecursor_normal(); -} - -sub show_progress() { - my $progress_box; - destroy_widget(); - gtkpack($status_box, - $progress_box = gtkpack_(Gtk2::VBox->new(0,10), - 0, Gtk2::Label->new(N("Building images for kernel:")), - 0, $plabel = Gtk2::Label->new(''), - 0, $progress = Gtk2::ProgressBar->new, - 1, Gtk2::HBox->new(0,0) - ) - ); - $central_widget = \$progress_box; - $progress_box->show_all; - mygtk2::flush(); -} - -sub update_progress { - my ($fraction, $total, $kernel) = @_; - $plabel->set_text($kernel); - $progress->set_fraction($fraction / $total); - mygtk2::flush(); -} - -sub add_pxe_entry { - my ($kernel, $nic) = @_; - my $pxeconf = get_platform_pxe() . "pxelinux.cfg/default"; - $kernel =~ s|vmlinuz-||; - my $label = uc($nic) . "." . uc($kernel); - my $conf = network::pxe::read_pxelinux_conf($pxeconf, undef); - push @{$conf->{entries}}, {label => $label , kernel => "vmlinuz-$kernel", initrd => "initrd-$nic.$kernel.img" }; - network::pxe::write_pxelinux_conf($conf, $pxeconf); -} - -sub del_pxe_entry { - my ($nbi) = @_; - my $pxeconf = get_platform_pxe() . "pxelinux.cfg/default"; - $nbi = basename($nbi); - $nbi =~ s|initrd-||; - $nbi =~ s|.img||; - my $conf = network::pxe::read_pxelinux_conf($pxeconf, undef); - - my $index = 0; - foreach (@{$conf->{entries}}) { - if ($_->{label} eq uc($nbi)) { - splice @{$conf->{entries}}, $index, 1; - last; - } - $index++; - } - network::pxe::write_pxelinux_conf($conf, $pxeconf); -} - -sub link_pxe { - my ($kernel, $nic) = @_; - my $pxedir = get_platform_pxe(); - $kernel =~ s|vmlinuz-||; - if ($nic) { - #- symlinkf does not work? - run_program::run("ln -sf ../../initrd-$nic.$kernel.img $pxedir"); - } else { - foreach (glob_("$tftpboot/initrd*.$kernel.img")) { - my $img = basename($_); - run_program::run("ln -sf ../../$img $pxedir"); - } - } -} - -sub get_platform_pxe() { - my $adir = "X86PC"; - $adir = "IA64PC" if arch() =~ /x86_64|ia64/; - $adir = "$tftpboot/$adir/linux/"; - return $adir; -} - -sub maintain_users() { - #- copy users from /etc/shadow to the client equivalent to allow ts login - my $user_box; - my @sys_users = cat_("/etc/shadow"); - my ($shadow_file, undef) = get_passwd_files(); - my @ts_users = cat_($shadow_file); - my $titer; - - #- use /homes to filter system daemons - #- seems suppressing root is less than useful, let it be added - my @homes = (all("/home"), "root"); - - my $list_model = Gtk2::ListStore->new("Glib::String"); - my $list_sys_users = Gtk2::TreeView->new_with_model($list_model); - $list_sys_users->append_column(Gtk2::TreeViewColumn->new_with_attributes(undef, Gtk2::CellRendererText->new, 'text' => 0)); - $list_sys_users->set_headers_visible(0); - - my $sys_user; - - foreach (@sys_users) { - my ($s_label) = split(/:/, $_, 2); - if (any { /$s_label/ } @homes) { - $list_model->append_set(0, $s_label); - } - } - - $list_sys_users->get_selection->signal_connect(changed => sub { - my ($model, $iter) = $_[0]->get_selected; - $model && $iter or return; - $sys_user = $model->get($iter, 0); - }); - - $list_model = Gtk2::ListStore->new("Glib::String"); - my $list_ts_users = Gtk2::TreeView->new_with_model($list_model); - $list_ts_users->append_column(Gtk2::TreeViewColumn->new_with_attributes(undef, Gtk2::CellRendererText->new, 'text' => 0)); - $list_ts_users->set_headers_visible(0); - - my $ts_user; - - foreach (@ts_users) { - my ($t_label) = split(/:/, $_, 2); - my @system_entry = grep { /$t_label/ } @sys_users; - $t_label = $t_label . " !!!" if $_ ne $system_entry[0]; - $list_model->append_set(0, $t_label); - } - - $list_ts_users->get_selection->signal_connect(changed => sub { - my ($model, $iter) = $_[0]->get_selected; - $model && $iter or return; - $ts_user = $model->get($iter, 0); - $ts_user =~ s| !!!||; - $titer = $iter; - }); - - gtkpack($status_box, - $user_box = gtkpack_(Gtk2::VBox->new(0,10), - 0, gtkadd(Gtk2::Label->new(N("!!! Indicates the password in the system database is different than\n the one in the Terminal Server database.\nDelete/re-add the user to the Terminal Server to enable login."))), - 0, gtkadd(Gtk2::HBox->new(0,20), - create_scrolled_window($list_sys_users), - gtkadd(Gtk2::VBox->new(1,10), - Gtk2::HBox->new(0,10), - gtksignal_connect(Gtk2::Button->new(N("Add User -->")), clicked => - sub { my $result = adduser($sys_user); - if ($result == 0) { - $list_model->append_set(0, $sys_user); - } - }), - gtksignal_connect(Gtk2::Button->new(N("<-- Del User")), clicked => - sub { deluser($ts_user); - $list_model->remove($titer); - }), - Gtk2::HBox->new(0,10), - ), - create_scrolled_window($list_ts_users), - ),), - ); - - $central_widget = \$user_box; - $user_box->show_all; -} - -sub maintain_clients() { - #- add client machines to Terminal Server config - my $client_box; - my %clients = read_dhcpd_conf(); - my $client; - my $citer; - my $local_config = 0; - my $button_edit; - my $button_config; - my $button_delete; - - #- client info in tree view - my $model = Gtk2::TreeStore->new("Glib::String"); - my $tree_clients = Gtk2::TreeView->new_with_model($model); - $tree_clients->append_column(Gtk2::TreeViewColumn->new_with_attributes(undef, Gtk2::CellRendererText->new, 'text' => 0)); - $tree_clients->set_headers_visible(0); - $tree_clients->get_selection->set_mode('browse'); - - foreach my $key (keys(%clients)) { - my $t_client = $model->append_set(undef, [ 0 => $key ]); - $model->append_set($t_client, [ 0 => $clients{$key}{hardware} ]); - $model->append_set($t_client, [ 0 => $clients{$key}{address} ]); - $model->append_set($t_client, [ 0 => N("type: %s", $clients{$key}{type}) ]); - if ($clients{$key}{filename}) { - $model->append_set($t_client, [ 0 => $clients{$key}{filename} ]); - } - $model->append_set($t_client, [ 0 => N("local config: %s", $clients{$key}{hdw_config}) ]); - - } - - $tree_clients->get_selection->signal_connect(changed => sub { - my ($model, $iter) = $_[0]->get_selected; - $model && $iter or return; - my $value = $model->get($iter, 0); - my $path = $model->get_path_str($iter); - if ($path !~ /:/) { - $client = $value; - $citer = $iter; - } else { - $citer = $model->iter_parent($iter); - $client = $model->get($citer, 0); - } - $button_edit->set_sensitive(1); - $button_config->set_sensitive(1); - $button_delete->set_sensitive(1); - }); - - #- entry boxes for client data entry - my $label_host = Gtk2::Label->new("Client Name:"); - my $entry_host = Gtk2::Entry->new; - set_help_tip($entry_host, 'client_name'); - my $label_mac = Gtk2::Label->new("MAC Address:"); - my $entry_mac = Gtk2::Entry->new; - set_help_tip($entry_mac, 'mac_address'); - my $label_ip = Gtk2::Label->new("IP Address:"); - my $entry_ip = Gtk2::Entry->new; - set_help_tip($entry_ip, 'ip_address'); - my $label_nbi = Gtk2::Label->new("Kernel Netboot Image:"); - my $entry_nbi = Gtk2::Combo->new; - set_help_tip($entry_nbi, 'netboot_image'); - - gtksignal_connect(my $check_hdw_config = Gtk2::CheckButton->new(N("Allow local hardware\nconfiguration.")), - clicked => sub { invbool \$local_config }); - set_help_tip($check_hdw_config, 'local_hardware'); - - my @images = grep { /\.nbi/ } all($tftpboot); - my $have_nbis = @images; - if ($have_nbis) { - unshift(@images, ""); - $entry_nbi->set_popdown_strings(@images); - } else { - $in->ask_warn(N("Error"), N("No net boot images created!")); - make_nbi(); - return 1; - } - - my $check_thin; - my $check_allow_thin; - my $is_thin = 0; - my $check_sync_kbd; - - gtkpack($status_box, - $client_box = gtkpack_(Gtk2::VBox->new(0,10), - 0, gtkadd(Gtk2::HBox->new(1,5), - gtkadd(Gtk2::VBox->new(0,5), - gtkadd($label_host), gtkadd($entry_host), - gtkadd($label_mac), gtkadd($entry_mac), - gtkadd($label_ip), gtkadd($entry_ip), - gtkadd($label_nbi), gtkadd($entry_nbi), - gtkadd($check_hdw_config), - gtksignal_connect($check_thin = Gtk2::CheckButton->new(N("Thin Client")), - clicked => sub { invbool \$is_thin }), - ), - gtkadd(Gtk2::VBox->new(1,10), - $check_allow_thin = Gtk2::CheckButton->new(N("Allow Thin Clients")), - $check_sync_kbd = Gtk2::CheckButton->new(N("Sync client X keyboard\n settings with server.")), - gtksignal_connect(Gtk2::Button->new(N("Add Client -->")), clicked => - sub { my $hostname = $entry_host->get_text; - my $mac = $entry_mac->get_text; - $mac =~ s/-| /:/g; #- dashes or spaces - if (length($mac) == 12) { - #- no delimiter - for (my $i = 10; $i >= 2; $i = $i-2) { substr($mac, $i, 0) = ":" } - } - local $_ = $mac; - if (length($mac) != 17 || (tr/://) != 5) { - $in->ask_warn(N("Error"), N("Unknown MAC address format")); - return; - } - my $ip = $entry_ip->get_text; - my $nbi = $entry_nbi->entry->get_text; - if ($hostname && $mac && $ip) { - - my $result = addclient($hostname, $mac, $ip, $nbi, $is_thin, $local_config); - - if ($result == 0) { - my $t_client = $model->append_set(undef, [ 0 => $hostname ]); - $model->append_set($t_client, [ 0 => $mac ]); - $model->append_set($t_client, [ 0 => $ip ]); - - my $client_type = N("type: fat"); - $client_type = N("type: thin") if $is_thin == 1; - $model->append_set($t_client, [ 0 => $client_type ]); - - $model->append_set($t_client, [ 0 => $nbi ]) if $nbi; - $check_thin->set_active(0); - $is_thin = 0; - - my $hdw_config = N("local config: false"); - $hdw_config = N("local config: true") if $local_config == 1; - $model->append_set($t_client, [ 0 => $hdw_config ]); - $check_hdw_config->set_active(0); - $local_config = 0; - %clients = read_dhcpd_conf(); - } - } - }), - gtksignal_connect($button_edit = Gtk2::Button->new(N("<-- Edit Client")), clicked => - sub { $entry_host->set_text($client); - $entry_mac->set_text($clients{$client}{hardware}); - $entry_ip->set_text($clients{$client}{address}); - my $type = $clients{$client}{type}; - if ($type eq "thin") { - $check_thin->set_active(1); - } else { - $check_thin->set_active(0); - } - $entry_nbi->entry->set_text($clients{$client}{filename}); - my $hdw_config = $clients{$client}{hdw_config}; - if ($hdw_config eq "true") { - $check_hdw_config->set_active(1); - } else { - $check_hdw_config->set_active(0); - } - my $result = delclient($client); - if ($result == 0) { - $model->remove($citer); - $button_edit->set_sensitive(0); - $button_config->set_sensitive(0); - $button_delete->set_sensitive(0); - } - }), - gtksignal_connect($button_config = Gtk2::Button->new(N("Disable Local Config")), clicked => - sub { - my $hdw_config = $clients{$client}{hdw_config}; - if ($hdw_config eq "true") { - client_hdw_config($clients{$client}{address}, 0); - } - }), - gtksignal_connect($button_delete = Gtk2::Button->new(N("Delete Client")), clicked => - sub { my $result = delclient($client); - if ($result == 0) { - $model->remove($citer); - $button_edit->set_sensitive(0); - $button_config->set_sensitive(0); - $button_delete->set_sensitive(0); - } - }), - ), - create_scrolled_window($tree_clients), - ), - ), - ); - - $check_allow_thin->set_active($conf{ALLOW_THIN}); - $check_sync_kbd->set_active($conf{SYNC_KBD}); - $check_thin->set_sensitive($conf{ALLOW_THIN}); - set_help_tip($check_thin, 'thin_client'); - gtksignal_connect($check_allow_thin, clicked => - sub { invbool \$conf{ALLOW_THIN}; - $check_thin->set_sensitive($conf{ALLOW_THIN}); - client_set("single"); - $in->ask_warn(N("Warning"), N("Need to restart the Display Manager for full changes to take effect. \n(service dm restart - at the console)")); - } - ); - gtksignal_connect($check_sync_kbd, clicked => - sub { invbool \$conf{SYNC_KBD}; - client_X_keyboard() if $conf{SYNC_KBD}; - } - ); - $button_edit->set_sensitive(0); - $button_config->set_sensitive(0); - $button_delete->set_sensitive(0); - $central_widget = \$client_box; - $client_box->show_all; -} - -sub client_X_keyboard() { - my $server_conf = "/etc/X11/xorg.conf"; - my $client_conf = '/etc/X11/xorg.conf$$CLIENT$$'; - my @server_X_config = cat_($server_conf); - foreach (@server_X_config) { - chomp; - if (/XkbModel/) { - my $oldmodel = `grep XkbModel '/etc/X11/xorg.conf\$\$CLIENT\$\$'`; - chomp $oldmodel; - my $newmodel = $_; - substInFile { s/$oldmodel/$newmodel/ } $client_conf; - log::explanations("Sync XkbModel in $client_conf from $server_conf"); - } - if (/XkbLayout/) { - my $oldlayout = `grep XkbLayout '/etc/X11/xorg.conf\$\$CLIENT\$\$'`; - chomp $oldlayout; - my $newlayout = $_; - substInFile { s/$oldlayout/$newlayout/ } $client_conf; - log::explanations("Sync XkbLayout in $client_conf from $server_conf"); - } - } -} - -sub client_set { - my ($default) = @_; - # we need to change some system files to allow the thin clients - # to access the server - enabling XDMCP and modify hosts.deny/hosts.allow for some security - # we also need to set runlevel to 5 and restart the display manager - my $inittab = $conf{USE_UNIONFS} ? "$common_prefix/etc/inittab" : '/etc/initab$$CLIENT$$'; - if ($conf{ALLOW_THIN} == 1) { - if (-f "/etc/sysconfig/autologin") { - my $answer = $in->ask_yesorno('', N("Thin clients will not work with autologin. Disable autologin?")); - if ($answer == 1) { - log::explanations("Renaming /etc/sysconfig/autologin to /etc/sysconfig/autologin.bak"); - `mv /etc/sysconfig/autologin /etc/sysconfig/autologin.bak`; - } - } - substInFile { s/id:3:initdefault:/id:5:initdefault:/ } "/etc/inittab"; - substInFile { s/DisplayManager.requestPort:/! DisplayManager.requestPort:/ } "/etc/X11/xdm/xdm-config"; - substInFile { s/Enable=false/Enable=true/ } "/usr/share/config/kdm/kdmrc"; - # This file had 2 "Enable=" entries, one for XDMCP and one for debug - change_gdm_xdmcp("true"); - log::explanations("Modified files /etc/inittab, /etc/X11/xdm/xdm-config, /usr/share/config/kdm/kdmrc, /etc/X11/gdm/gdm.conf"); - # just XDMCP in hosts.allow is enough for xdm & kdm, but gdm does not work - x11 does not help either - update_hosts_allow("enable"); - if ($default eq "all") { - $in->ask_warn(N("Warning"), N("All clients will use %s", $inittab)); - renamef($inittab, "$inittab.fat") if -f $inittab; - write_thin_inittab("CLIENT"); - } - } else { - if (-f "/etc/sysconfig/autologin.bak") { - log::explanations("Renaming /etc/sysconfig/autologin.bak to /etc/sysconfig/autologin"); - `mv /etc/sysconfig/autologin.bak /etc/sysconfig/autologin`; - } - substInFile { s/id:5:initdefault:/id:3:initdefault:/ } '/etc/inittab'; - substInFile { s/! DisplayManager.requestPort:/DisplayManager.requestPort:/ } "/etc/X11/xdm/xdm-config"; - substInFile { s/Enable=true/Enable=false/ } "/usr/share/config/kdm/kdmrc"; - change_gdm_xdmcp("false"); - log::explanations("Modified files /etc/inittab, /etc/X11/xdm/xdm-config, /usr/share/config/kdm/kdmrc, /etc/X11/gdm/gdm.conf"); - update_hosts_allow("disable"); - renamef("$inittab.fat", $inittab) if $default eq "all" && -f "$inittab.fat"; - } - $clients_set = 1; -} - -sub dhcpd_config() { - #- do main dhcp server config - my $dhcpd_box; - my @ifvalues; - my @resolve; - my %netconfig; - my @nservers; - my $button_msg; - my $new_config = 0; - my $dh_button; - my $wrote = 0; - - #- entry boxes for data entry - my $box_subnet = Gtk2::HBox->new(0,0); - my $label_subnet = Gtk2::Label->new(N("Subnet:")); - $label_subnet->set_justify('right'); - my $entry_subnet = Gtk2::Entry->new; - $box_subnet->pack_end($entry_subnet, 0, 0, 2); - $box_subnet->pack_end($label_subnet, 0, 0, 2); - - my $box_netmask = Gtk2::HBox->new(0,0); - my $label_netmask = Gtk2::Label->new(N("Netmask:")); - $label_netmask->set_justify('left'); - my $entry_netmask = Gtk2::Entry->new; - $box_netmask->pack_end($entry_netmask, 0, 0, 2); - $box_netmask->pack_end($label_netmask, 0, 0, 2); - - my $box_routers = Gtk2::HBox->new(0,0); - my $label_routers = Gtk2::Label->new(N("Routers:")); - $label_routers->set_justify('left'); - my $entry_routers = Gtk2::Entry->new; - $box_routers->pack_end($entry_routers, 0, 0, 2); - $box_routers->pack_end($label_routers, 0, 0, 2); - - my $box_subnet_mask = Gtk2::HBox->new(0,0); - my $label_subnet_mask = Gtk2::Label->new(N("Subnet Mask:")); - $label_subnet_mask->set_justify('left'); - my $entry_subnet_mask = Gtk2::Entry->new; - $box_subnet_mask->pack_end($entry_subnet_mask, 0, 0, 2); - $box_subnet_mask->pack_end($label_subnet_mask, 0, 0, 2); - - my $box_broadcast = Gtk2::HBox->new(0,0); - my $label_broadcast = Gtk2::Label->new(N("Broadcast Address:")); - $label_broadcast->set_justify('left'); - my $entry_broadcast = Gtk2::Entry->new; - $box_broadcast->pack_end($entry_broadcast, 0, 0, 2); - $box_broadcast->pack_end($label_broadcast, 0, 0, 2); - - my $box_domain = Gtk2::HBox->new(0,0); - my $label_domain = Gtk2::Label->new(N("Domain Name:")); - $label_domain->set_justify('left'); - my $entry_domain = Gtk2::Entry->new; - $box_domain->pack_end($entry_domain, 0, 0, 2); - $box_domain->pack_end($label_domain, 0, 0, 2); - - my $box_name_servers = Gtk2::HBox->new(0,0); - my $box_name_servers_entry = Gtk2::VBox->new(0,0); - my $label_name_servers = Gtk2::Label->new(N("Name Servers:")); - $label_name_servers->set_justify('left'); - my $entry_name_server1 = Gtk2::Entry->new; - my $entry_name_server2 = Gtk2::Entry->new; - my $entry_name_server3 = Gtk2::Entry->new; - $box_name_servers_entry->pack_start($entry_name_server1, 0, 0, 0); - $box_name_servers_entry->pack_start($entry_name_server2, 0, 0, 0); - $box_name_servers_entry->pack_start($entry_name_server3, 0, 0, 0); - $box_name_servers->pack_end($box_name_servers_entry, 0, 0, 2); - $box_name_servers->pack_end($label_name_servers, 0, 0, 2); - - my $label_ip_range_start = Gtk2::Label->new(N("IP Range Start:")); - my $label_ip_range_end = Gtk2::Label->new(N("IP Range End:")); - my $entry_ip_range_start = Gtk2::Entry->new; - my $entry_ip_range_end = Gtk2::Entry->new; - - #- grab some default entries from the running system - - if (-e "/etc/sysconfig/network") { - %netconfig = getVarsFromSh("/etc/sysconfig/network"); - $entry_domain->set_text($netconfig{DOMAINNAME}); - } - - my $sys_netmask = get_mask_from_sys(); - $entry_netmask->set_text($sys_netmask); - $entry_subnet_mask->set_text($sys_netmask); - - my $sys_broadcast = get_broadcast_from_sys(); - $entry_broadcast->set_text($sys_broadcast); - my $sys_subnet = get_subnet_from_sys($sys_broadcast, $sys_netmask); - - $entry_subnet->set_text($sys_subnet); - - my @route = grep { /^0.0.0.0/ } `/sbin/route -n`; - @ifvalues = split(/[ \t]+/, $route[0]); - $entry_routers->set_text($ifvalues[1]); - - @resolve = cat_("/etc/resolv.conf"); - my $i = 1; - chop(@resolve); - - foreach (@resolve) { - @ifvalues = split / /; - if ($ifvalues[0] =~ /nameserver/ && $i < 4) { - $nservers[$i++] = $ifvalues[1]; - } - } - - $entry_name_server1->set_text($nservers[1]); - $entry_name_server2->set_text($nservers[2]); - $entry_name_server3->set_text($nservers[3]); - - my $dhcpd_conf = cat_("/etc/dhcpd.conf"); - if (-e "/etc/dhcpd.conf" && $dhcpd_conf !~ /drakTermServ/) { - $button_msg = N("Append TS Includes To Existing Config"); - } else { - $button_msg = N("Write Config"); - $new_config = 1; - } - - gtkpack($status_box, - $dhcpd_box = gtkpack_(Gtk2::HBox->new(1,10), - 0, gtkadd(Gtk2::VBox->new, - gtkadd($box_subnet), - gtkadd($box_netmask), - gtkadd($box_routers), - gtkadd($box_subnet_mask), - gtkadd($box_broadcast), - gtkadd($box_domain), - gtkadd($box_name_servers), - ), - 0, gtkadd(Gtk2::VBox->new(0,0), - Gtk2::Label->new(N("dhcpd Server Configuration") . "\n\n" . - N("Most of these values were extracted\nfrom your running system.\nYou can modify as needed.")), - Gtk2::HSeparator->new, - gtkadd(Gtk2::HBox->new, - Gtk2::Label->new(N("Dynamic IP Address Pool\n(needed for PXE clients):")), - ), - gtkadd(Gtk2::HBox->new(0,0), - gtkadd(Gtk2::VBox->new, - gtkadd($label_ip_range_start), - gtkadd($entry_ip_range_start), - ), - gtkadd(Gtk2::VBox->new, - gtkadd($label_ip_range_end), - gtkadd($entry_ip_range_end), - ), - ), - gtkadd(Gtk2::HBox->new), - gtksignal_connect($dh_button = Gtk2::Button->new($button_msg), clicked => - sub { - if ($new_config == 1) { - $wrote = write_dhcpd_config("full", - $entry_subnet->get_text, - $entry_netmask->get_text, - $entry_routers->get_text, - $entry_subnet_mask->get_text, - $entry_broadcast->get_text, - $entry_domain->get_text, - $entry_name_server1->get_text, - $entry_name_server2->get_text, - $entry_name_server3->get_text, - $entry_ip_range_start->get_text, - $entry_ip_range_end->get_text); - } else { - if ($dhcpd_conf =~ /dhcpd.conf.terminal-server/) { - $wrote = 1; - $config_written = 1; - } else { - $wrote = write_dhcpd_config("append", @nothing); - } - } - $dh_button->set_sensitive(0) if $wrote; - } - ), - Gtk2::HBox->new(0,10), - ), - ), - ); - - $central_widget = \$dhcpd_box; - $dhcpd_box->show_all; -} - -sub get_net_interface() { - my @interfaces = `/sbin/route | grep -v lo | grep -v vmnet | tail +3 | awk '{print \$8}' | uniq`; - chop @interfaces; - my $count = @interfaces; - if ($count == 1) { - return @interfaces[0]; - } else { - foreach (@interfaces) { - my $is_default = `/sbin/route | grep $_ | grep default`; - return $_ if !$is_default; - } - } -} - -sub get_mask_from_sys() { - my %netconfig; - if (-e "/etc/sysconfig/network-scripts/ifcfg-$interface") { - %netconfig = getVarsFromSh("/etc/sysconfig/network-scripts/ifcfg-$interface"); - $netconfig{NETMASK}; - } -} - -sub get_subnet_from_sys { - my ($sys_broadcast, $sys_netmask) = @_; - my @subnet; - - my @netmask = split(/\./, $sys_netmask); - my @broadcast = split(/\./, $sys_broadcast); - - foreach (0..3) { - #- wasn't evaluating the & as expected - my $val1 = $broadcast[$_] + 0; - my $val2 = $netmask[$_] + 0; - $subnet[$_] = $val1 & $val2; - } - - join(".", @subnet); -} - -sub get_broadcast_from_sys() { - my @ifconfig = grep { /inet/ } `/sbin/ifconfig $interface`; - my @ifvalues = split(/[: \t]+/, $ifconfig[0]); - - $ifvalues[5]; -} - -sub get_ip_from_sys() { - my @ifconfig = grep { /inet/ } `/sbin/ifconfig $interface`; - my @ifvalues = split(/[: \t]+/, $ifconfig[0]); - - $ifvalues[3]; -} - -sub write_dhcpd_config { - my ($mode, $subnet, $netmask, $routers, $subnet_mask, $broadcast, $domain, $ns1, $ns2, $ns3, $pool_start, $pool_end) = @_; - my @dhcpd_config; - my @includes; - push @includes, qq(# Include PXE definitions and defaults\ninclude "/etc/dhcpd.conf.pxe.include";\n) if $conf{CREATE_PXE}; - push @includes, qq(# Include Etherboot definitions and defaults\ninclude "/etc/dhcpd.conf.etherboot.include";\n); - push @includes, qq(# Include Etherboot default kernel version\ninclude "/etc/dhcpd.conf.etherboot.kernel";\n); - if ($mode eq "append") { - append_to_file("/etc/dhcpd.conf", qq(include "/etc/dhcpd.conf.terminal-server";\n)); - push @dhcpd_config, @includes; - push @dhcpd_config, qq(# Include client machine configurations\ninclude "$client_cfg";\n); - $config_written = write_and_check("/etc/dhcpd.conf.terminal-server", @dhcpd_config); - return $config_written; - } - - $nfs_subnet = $subnet; - $nfs_mask = $subnet_mask; - - push @dhcpd_config, "#dhcpd.conf - generated by drakTermServ\n\n"; - push @dhcpd_config, "ddns-update-style none;\n\n"; - push @dhcpd_config, "# Long leases (48 hours)\ndefault-lease-time 172800;\nmax-lease-time 172800;\n\n"; - push @dhcpd_config, @includes; - push @dhcpd_config, "# Network-specific section\n\n"; - - push @dhcpd_config, "subnet $subnet netmask $netmask {\n"; - push @dhcpd_config, "\toption routers $routers;\n" if $routers; - push @dhcpd_config, "\toption subnet-mask $subnet_mask;\n" if $subnet_mask; - push @dhcpd_config, "\toption broadcast-address $broadcast;\n" if $broadcast; - push @dhcpd_config, qq(\toption domain-name "$domain";\n) if $domain; - - my $pool_string = $pool_start && $pool_end && "\trange dynamic-bootp " . $pool_start . " " . $pool_end . ";\n"; - push @dhcpd_config, $pool_string if $pool_string; - - my $ns_string = $ns1 && "\toption domain-name-servers " . $ns1; - $ns_string = $ns2 && $ns_string . ", " . $ns2; - $ns_string = $ns3 && $ns_string . ", " . $ns3; - $ns_string = $ns_string . ";\n" if $ns_string; - push @dhcpd_config, $ns_string if $ns_string; - - push @dhcpd_config, "}\n\n"; - - push @dhcpd_config, qq(# Include client machine configurations\ninclude "$client_cfg";\n); - $config_written = write_and_check("/etc/dhcpd.conf", @dhcpd_config); - return $config_written; -} - -sub write_and_check { - my ($ofile, @values) = @_; - output_p($ofile, @values); - my $written = cat_($ofile); - my $source = join("", @values); - if ($written ne $source) { - $in->ask_warn(N("Error"), N("Write to %s failed!", $ofile)); - return 0; - } - return 1; -} - -sub write_eb_image { - #- write a bootable etherboot CD image or floppy - pxe images too - my ($nic, $rom_path, $type) = @_; - $in->ask_warn(N("Error"), N("No NIC selected!")) and return if $nic eq ''; - if ($type eq 'floppy') { - my $in = interactive->vnew; - if (-e "/dev/fd0") { - my $result = $in->ask_okcancel('', N("Please insert floppy disk:")); - return if !($result); - $result = run_program::run("cat $rom_path/zdsk/$nic > /dev/fd0"); - if ($result == 0) { - $in->ask_warn(N("Error"), N("Could not access the floppy!")); - } else { - $in->ask_warn(N("Information"), N("Floppy can be removed now")); - } - } else { - $in->ask_warn(N("Error"), N("No floppy drive available!")); - } - } elsif ($type eq 'pxe') { - $nic =~ s/.zdsk/.zpxe/; - run_program::run("cp $rom_path/zpxe/$nic $tftpboot"); - if (-e "$tftpboot/$nic") { - $in->ask_warn(N("Information"), N("PXE image is %s/%s", $tftpboot, $nic)); - } else { - $in->ask_warn(N("Error"), N("Error writing %s/%s", $tftpboot, $nic)); - } - } else { - my $installed = $in->do_pkgs->install('mkisofs') || -f "/usr/bin/mksofs"; - if ($installed) { - my $tmp = "/root/tmp"; - mkdir_p("$tmp/eb"); - run_program::run("cat $rom_path/zdsk/$nic > $tmp/eb/eb.img"); - run_program::run("dd if=/dev/zero of=$tmp/eb/eb.img bs=512 seek=72 count=2808"); - run_program::run("mkisofs -b eb.img -o $tmp/$nic.iso $tmp/eb"); - rm_rf("$tmp/eb"); - if (-e "$tmp/$nic.iso") { - $in->ask_warn(N("Information"), N("Etherboot ISO image is %s", "$tmp/$nic.iso")); - return; - } - } - $in->ask_warn(N("Error"), N("Something went wrong! - Is mkisofs installed?")); - } -} - -sub enable_ts() { - #- setup default config files for terminal server - - check_gdm(); - - @buff = (); - $buff[0] = "Enabling Terminal Server...\n\n"; - $buff[1] = "\tChecking default /etc/dhcpd.conf...\n"; - my $dhcpd_conf = cat_("/etc/dhcpd.conf"); - if ($dhcpd_conf !~ /drakTermServ/) { - if (-f "/etc/dhcpd.conf") { - write_dhcpd_config("append", @nothing) if $dhcpd_conf !~ /dhcpd.conf.terminal-server/; - } else { - if ($cmd_line == 1) { - print("No /etc/dhcpd.conf built yet - use GUI to create!!\n"); - } else { - $in->ask_warn(N("Error"), N("Need to create /etc/dhcpd.conf first!")); - dhcpd_config(); - } - return; - } - } - #- suggestion from jmdault - not always needed - if (! -f $client_cfg) { - touch($client_cfg); - } - my $buff_index = toggle_chkconfig("on", "dhcpd", 2); - $buff[$buff_index] = "\tSetting up default /etc/exports...\n"; - cp_af("/etc/exports", "/etc/exports.mdkTS") if -e "/etc/exports"; - my $squash = "root_squash"; - my %msec = getVarsFromSh("/etc/sysconfig/msec"); - $squash = "no_root_squash" if $msec{SECURE_LEVEL} > 2; - my $exports = "#/etc/exports - generated by drakTermServ\n\n"; - if ($nfs_subnet eq '') { - $nfs_mask = get_mask_from_sys(); - my $sys_broadcast = get_broadcast_from_sys(); - $nfs_subnet = get_subnet_from_sys($sys_broadcast, $nfs_mask); - } - $exports .= "/\t$nfs_subnet/$nfs_mask(ro,$squash)\n"; - $exports .= "/home\t$nfs_subnet/$nfs_mask(rw,root_squash)\n"; - $exports .= "$client_prefix\t$nfs_mask(rw, $squash)\n" if $conf{USE_UNIONFS}; - output_p("/etc/exports", $exports); - $buff_index = toggle_chkconfig("on", "portmap", $buff_index+1); - $buff_index = toggle_chkconfig("on", $nfs_daemon, $buff_index+1); - $buff_index = toggle_chkconfig("on", "tftp", $buff_index); - $buff_index = service_change("xinetd", "restart", $buff_index); - $buff[$buff_index] = "\n\tDone!"; - - if ($cmd_line == 1) { - print "@buff\n"; - return; - } - - show_status(@buff); -} - -sub disable_ts() { - #- restore pre-terminal server configs - - @buff = (); - $buff[0] = "Disabling Terminal Server...\n\n"; - $buff[1] = "\tRestoring original /etc/dhcpd.conf...\n"; - cp_af("/etc/dhcpd.conf.mdkTS", "/etc/dhcpd.conf") if -e "/etc/dhcpd.conf.mdkTS"; - substInFile { s|include "/etc/dhcpd.conf.terminal-server";|| } "/etc/dhcpd.conf"; - my $buff_index = toggle_chkconfig("off", "dhcpd", 2); - $buff[$buff_index] = "\tRestoring default /etc/exports...\n"; - cp_af("/etc/exports.mdkTS", "/etc/exports") if -e "/etc/exports.mdkTS"; - $buff_index = toggle_chkconfig("off", "portmap", $buff_index+1); - $buff_index = toggle_chkconfig("off", $nfs_daemon, $buff_index+1); - $buff_index = toggle_chkconfig("off", "tftp", $buff_index); - $buff_index = service_change("xinetd", "restart", $buff_index); - $buff[$buff_index] = "\n\tDone!"; - - if ($cmd_line == 1) { - print "@buff\n"; - return; - } - - show_status(@buff); -} - -sub toggle_chkconfig { - #- change service config - my ($state, $service, $buff_index) = @_; - run_program::run("/sbin/chkconfig $service $state"); - $buff[$buff_index] = "\tTurning $service $state...\n"; - $buff_index++; - $buff_index; -} - -sub service_change { - my ($service, $command, $buff_index) = @_; - run_program::run("BOOTUP=serial /sbin/service $service $command > /tmp/drakTSservice.status 2>&1"); - my @result = cat_("/tmp/drakTSservice.status"); - foreach (@result) { - $buff[$buff_index] = "\t$_"; - $buff_index++; - } - unlink "/tmp/drakTSservice.status"; - $buff_index; -} - -sub start_ts() { - #- start the terminal server - my $pcimap = "/etc/dhcpd.conf.etherboot-pcimap.include"; - - @buff = (); - if (-f $pcimap) { - $buff[0] = "Starting Terminal Server...\n\n"; - touch("/etc/dhcpd.conf.etherboot.kernel") if ! -f "/etc/dhcpd.conf.etherboot.kernel"; - my $buff_index = service_change("dhcpd", "start", 2); - $buff_index = service_change("portmap", "start", $buff_index); - $buff_index = service_change($nfs_daemon, "start", $buff_index); - $buff[$buff_index] = "\n\tDone!"; - } else { - $buff[0] = "Missing $pcimap - please create net boot images for at least one kernel."; - } - - if ($cmd_line == 1) { - print "@buff\n"; - return; - } - - show_status(@buff); -} - -sub stop_ts() { - #- stop the terminal server - - @buff = (); - $buff[0] = "Stopping Terminal Server...\n\n"; - my $buff_index = service_change("dhcpd", "stop", 2); - $buff_index = service_change("portmap", "stop", $buff_index); - $buff_index = service_change($nfs_daemon, "stop", $buff_index); - $buff[$buff_index] = "\n\tDone!"; - - return if $in_wizard; - - if ($cmd_line == 1) { - print "@buff\n"; - return; - } - - show_status(@buff); - -} - -#- for the wizard, stop the server first -sub restart_ts() { - stop_ts(); - start_ts(); -} - -sub show_status() { - text_view("@buff", "close"); -} - -sub get_passwd_files() { - my $shadow = $conf{USE_UNIONFS} ? "$common_prefix/etc/shadow" : '/etc/shadow$$CLIENT$$'; - my $passwd = $conf{USE_UNIONFS} ? "$common_prefix/etc/passwd" : '/etc/passwd$$CLIENT$$'; - return $shadow, $passwd; -} - -sub adduser { - my ($username) = @_; - my @active_users = cat_("/etc/shadow"); - my @passwd_users = cat_("/etc/passwd"); - my ($shadow_file, $passwd_file) = get_passwd_files(); - my @ts_users = cat_($shadow_file); - my $is_user = any { /$username/ } @active_users; - my $add_fail = 0; - my $in_already; - - if ($is_user) { - my @shadow_entry = grep { /$username/ } @active_users; - my @passwd_entry = grep { /$username/ } @passwd_users; - my $is_ts_user = any { /$username/ } @ts_users; - if ($is_ts_user) { - my @ts_shadow = grep { /$username/ } @ts_users; - if ($shadow_entry[0] eq $ts_shadow[0]) { - $in_already = 1; - } else { - #in but password changed - print N("%s passwd bad in Terminal Server - rewriting...\n", $username); - deluser($username); - adduser($username); - } - } else { - # new ts user - append_to_file($shadow_file, $shadow_entry[0]) or $add_fail = 1; - append_to_file($passwd_file, $passwd_entry[0]) or $add_fail = 1; - $in_already = 0; - } - } - - if ($cmd_line == 1) { - print N("%s is not a user..\n", $username) if !($is_user); - print N("%s is already a Terminal Server user\n", $username) if $in_already; - if ($add_fail == 1 || $in_already || !$is_user) { - print N("Addition of %s to Terminal Server failed!\n", $username); - } else { - print N("%s added to Terminal Server\n", $username); - } - return; - } else { - $in_already; - } -} - -sub deluser { - # del a user from the client shadow file - my ($username) = @_; - my $user_deleted; - my ($shadow_file, $passwd_file) = get_passwd_files(); - substInFile { $_ = '', $user_deleted = 1 if begins_with($_, "$username:") } $shadow_file; - substInFile { $_ = '', $user_deleted = 1 if begins_with($_, "$username:") } $passwd_file; - - if ($cmd_line == 1) { - if ($user_deleted) { - print N("Deleted %s...\n", $username); - } else { - print N("%s not found...\n", $username); - } - return; - } -} - -sub addclient { - #- add a new client entry after checking for dups - my ($hostname, $mac, $ip, $nbi, $is_thin, $local_config) = @_; - - my $host_in_use = 0; - my $mac_in_use = 0; - my $ip_in_use = 0; - my %ts_clients = read_dhcpd_conf(); - - foreach my $client (keys(%ts_clients)) { - $host_in_use = 1 if $hostname eq $client; - $mac_in_use = 1 if $mac eq $ts_clients{$client}{hardware}; - $ip_in_use = 1 if $ip eq $ts_clients{$client}{address}; - } - - if ($cmd_line == 1) { - print N("%s already in use\n", $hostname) if $host_in_use; - print N("%s already in use\n", $mac) if $mac_in_use; - print N("%s already in use\n", $ip) if $ip_in_use; - if ($host_in_use || $mac_in_use || $ip_in_use) { - return; - } - } - - if (!$host_in_use && !$mac_in_use && !$ip_in_use) { - $ts_clients{$hostname}{hardware} = $mac; - $ts_clients{$hostname}{address} = $ip; - if ($is_thin == 1) { - $ts_clients{$hostname}{type} = "thin"; - } else { - $ts_clients{$hostname}{type} = "fat"; - } - $ts_clients{$hostname}{filename} = $nbi; - if ($local_config == 1) { - $ts_clients{$hostname}{hdw_config} = "true"; - client_hdw_config($ip, 1); - } else { - $ts_clients{$hostname}{hdw_config} = "false"; - client_hdw_config($ip, 0); - } - my $client_entry = format_client_entry($hostname, %ts_clients); - append_to_file($client_cfg, $client_entry); - $changes_made = 1; - create_client_sysnetwork($hostname, $ip); - 0; - } -} - -sub delclient { - #- find a client and delete the entry in dhcpd.conf - my ($hostname) = @_; - my $host_found; - - my %ts_clients = read_dhcpd_conf(); - - foreach my $client (keys(%ts_clients)) { - if ($hostname eq $client) { - $host_found = 1; - clean_client_config($ts_clients{$client}{address}); - delete $ts_clients{$client}; - write_dhcpd_conf(%ts_clients); - $changes_made = 1; - return 0; - } - } - - if ($cmd_line == 1) { - print N("%s not found...\n", $hostname) unless $host_found; - return; - } -} - -sub change_gdm_xdmcp { - my ($enable) = @_; - my @conf_data = cat_("/etc/X11/gdm/gdm.conf"); - for (my $i = 0; $i < @conf_data; $i++) { - $conf_data[$i] =~ s/^Enable=false/Enable=true/ if $enable eq "true"; - $conf_data[$i] =~ s/^Enable=true/Enable=false/ if $enable eq "false"; - # bail here so we do not alter the debug setting - if ($conf_data[$i] eq "[debug]\n") { - output("/etc/X11/gdm/gdm.conf", @conf_data); - last; - } - } -} - -sub update_hosts_allow { - my ($mode) = @_; - my $mask = get_mask_from_sys(); - my $subnet = `/sbin/ip route list dev $interface scope link | cut -f1 -d"/"`; - chop $subnet; - my $i; - if ($mode eq "enable") { - my $has_all = `grep ALL /etc/hosts.allow`; - if ($has_all) { - $in->ask_warn(N("Warning"), N("/etc/hosts.allow and /etc/hosts.deny already configured - not changed")); - return; - } - if (!$has_all) { - log::explanations("Modified file /etc/hosts.allow"); - append_to_file("/etc/hosts.allow", "ALL:\t$subnet/$mask 127.0.0.1\n"); - } - $has_all = `grep ALL /etc/hosts.deny`; - if (!$has_all) { - log::explanations("Modified file /etc/hosts.deny"); - append_to_file("/etc/hosts.deny", "ALL:\tALL\n"); - } - } - if ($mode eq "disable") { - my @allow = cat_("/etc/hosts.allow"); - for ($i = 0; $i < @allow; $i++) { - if ($allow[$i] =~ /^ALL:\t$subnet/) { - splice(@allow, $i, 1); - log::explanations("Modified file /etc/hosts.allow"); - output("/etc/hosts.allow", @allow); - last; - } - } - my @deny = cat_("/etc/hosts.deny"); - for ($i = 0; $i < @deny; $i++) { - if ($deny[$i] =~ /^ALL:\tALL/) { - splice(@deny, $i, 1); - log::explanations("Modified file /etc/hosts.deny"); - output("/etc/hosts.deny", @deny); - last; - } - } - } -} - -sub format_client_entry { - #- create a client entry, in proper format - my ($client, %ts_clients) = @_; - my $entry = qq(host $client {\n); - $entry .= qq(\thardware ethernet\t$ts_clients{$client}{hardware};\n); - $entry .= qq(\tfixed-address\t\t$ts_clients{$client}{address};\n); - $entry .= qq(\t#type\t\t\t$ts_clients{$client}{type};\n) if $ts_clients{$client}{type}; - $entry .= qq(\tfilename\t\t"$ts_clients{$client}{filename}";\n) if $ts_clients{$client}{filename}; - $entry .= qq(\t#hdw_config\t\t$ts_clients{$client}{hdw_config};\n) if $ts_clients{$client}{hdw_config}; - $entry .= qq(}\n); - if ($ts_clients{$client}{type} eq "thin") { - write_thin_inittab($ts_clients{$client}{address}); - } else { - if ($conf{USE_UNIONFS}) { - eval { rm_rf("$ts_prefix/$ts_clients{$client}{address}etc/inittab") }; - } else { - eval { rm_rf("/etc/inittab\$\$IP=$ts_clients{$client}{address}\$\$") }; - } - } - $entry; -} - -sub write_dhcpd_conf { - my %ts_clients = @_; - my @client_data; - foreach my $key (keys(%ts_clients)) { - my $client_entry = format_client_entry($key, %ts_clients); - push @client_data, $client_entry; - } - output_p($client_cfg, @client_data); -} - -sub read_dhcpd_conf() { - my $clients = $client_cfg; - my %ts_clients; - my $hostname; - - #- read and parse current client entries - my @client_data = cat_($clients); - foreach (@client_data) { - my ($name, $val, $val2) = split ' '; - $val = $val2 if $name =~ /hardware/; - $val =~ s/[;"]//g; - if ($name !~ /}/) { - if ($name =~ /host/) { - $hostname = $val; - } else { - $name = "address" if $name =~ /fixed-address/; - $name = "type" if $name =~ /#type/; - $name = "hdw_config" if $name =~ /#hdw_config/; - $ts_clients{$hostname}{$name} = $val; - } - } - } - %ts_clients; -} - -sub client_hdw_config { - my ($client_ip, $mode) = @_; - # configure the files for a client to be able to - # run drak tools locally and modify configs - # mode 0 disables root logins but retains configs - # mode 1 creates the new template files - my $suffix = $conf{USE_UNIONFS} ? "" : "\$\$IP=$client_ip\$\$"; - my $prefix = $conf{USE_UNIONFS} ? "$client_prefix/$client_ip" : ""; - if ($mode == 1) { - log::explanations("Allowing root access for $client_ip"); - my ($shadow_file, undef) = get_passwd_files(); - cp_af($shadow_file, "$prefix/etc/shadow$suffix"); - my @sys_users = cat_("/etc/shadow"); - foreach (@sys_users) { - if (/^root:/) { - # need root access to do the hardware config - append_to_file("$prefix/etc/shadow$suffix", $_); - last; - } - } - # make all the local config files - cp_af("/etc/sysconfig/mouse", "$prefix/etc/sysconfig/mouse$suffix") if -f "/etc/sysconfig/mouse"; - cp_af("/etc/X11/XF86Config", "$prefix/etc/X11/XF86Config$suffix") if -f "/etc/X11/XF86Config"; - if ($conf{USE_UNIONFS}) { - cp_af("$common_prefix/etc/X11/xorg.conf", "$prefix/etc/X11/xorg.conf") if -f "$common_prefix/etc/X11/xorg.conf"; - } else { - cp_af('/etc/X11/xorg.conf$$CLIENT$$', "/etc/X11/xorg.conf$suffix") if -f '/etc/X11/xorg.conf$$CLIENT$$'; - } - output("$prefix/etc/modules.conf$suffix", ''); - output("$prefix/etc/modules$suffix", ''); - output("$prefix/etc/modprobe.conf$suffix", ''); - output("$prefix/etc/modprobe.preload$suffix", ''); - # create mount points so they can be edited by the client - if (!$conf{USE_UNIONFS}) { - my $mnt_access = "$client_ip(rw,no_root_squash)"; - append_to_file("/etc/exports", "/etc/sysconfig/mouse$suffix\t$mnt_access\n"); - append_to_file("/etc/exports", "/etc/modules.conf$suffix\t$mnt_access\n"); - append_to_file("/etc/exports", "/etc/modules$suffix\t$mnt_access\n"); - append_to_file("/etc/exports", "/etc/modprobe.conf$suffix\t$mnt_access\n"); - append_to_file("/etc/exports", "/etc/modprobe.preload$suffix\t$mnt_access\n"); - append_to_file("/etc/exports", "/etc/X11/XF86Config$suffix\t$mnt_access\n"); - append_to_file("/etc/exports", "/etc/X11/xorg.conf$suffix\t$mnt_access\n"); - } - } else { - log::explanations("Removing root access for $client_ip"); - eval { rm_rf("/etc/shadow\$\$IP=$client_ip\$\$") }; - remove_client_mounts($client_ip); - } -} - -sub create_client_sysnetwork { - #- this lets gnome operate properly since udhcpc does not get the hostname from the dhcpd server - my ($hostname, $ip) = @_; - log::explanations("Adding /etc/sysconfig/network for $ip"); - my $network_file = $conf{USE_UNIONFS} ? "$client_prefix/$ip/etc/sysconfig/network" : "/etc/sysconfig/network\$\$IP=$ip\$\$"; - my @net_data = ("HOSTNAME=$hostname\n", "NETWORKING=yes\n", "FORWARD_IPV4=false\n"); - output_p($network_file, @net_data); -} - -sub restart_server() { - my $answer = $in->ask_yesorno('', N("Configuration changed - restart %s/dhcpd?", $nfs_daemon)); - if ($answer == 1) { - stop_ts(); - start_ts(); - $changes_made = 0; - } -} - -sub clean_client_config { - my ($client_ip) = @_; - # this routine entirely removes local hardware config settings - log::explanations("Removing all local hardware config for $client_ip"); - my $suffix = $conf{USE_UNIONFS} ? "" : "\$\$IP=$client_ip\$\$"; - my $prefix = $conf{USE_UNIONFS} ? "$client_prefix/$client_ip" : ""; - eval { rm_rf("$prefix/etc/shadow$suffix") }; - eval { rm_rf("$prefix/etc/sysconfig/mouse$suffix") }; - eval { rm_rf("$prefix/etc/modules.conf$suffix") }; - eval { rm_rf("$prefix/etc/modules$suffix") }; - eval { rm_rf("$prefix/etc/modprobe.conf$suffix") }; - eval { rm_rf("$prefix/etc/modprobe.preload$suffix") }; - eval { rm_rf("$prefix/etc/X11/XF86Config$suffix") }; - eval { rm_rf("$prefix/etc/X11/xorg.conf$suffix") }; - eval { rm_rf("$prefix/etc/sysconfig/network$suffix") }; - remove_client_mounts($client_ip); -} - -sub remove_client_mounts { - my ($client_ip) = @_; - #remove the mount points also - log::explanations("Removing read/write mount points for $client_ip"); - substInFile { - $_ = '' if /$client_ip/; - } "/etc/exports"; -} - -sub destroy_widget() { - if ($central_widget ne '') { - $$central_widget->destroy; - $central_widget = ''; - } -} |