diff options
Diffstat (limited to 'perl-install/standalone/drakTermServ')
-rwxr-xr-x | perl-install/standalone/drakTermServ | 1578 |
1 files changed, 0 insertions, 1578 deletions
diff --git a/perl-install/standalone/drakTermServ b/perl-install/standalone/drakTermServ deleted file mode 100755 index e5a4a95d2..000000000 --- a/perl-install/standalone/drakTermServ +++ /dev/null @@ -1,1578 +0,0 @@ -#!/usr/bin/perl -# -# Copyright (C) 2002 by MandrakeSoft (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. -# -# first pass at an interactive tool to help setup/maintain the Mandrake -# Terminal Server implementation -# -# Requires: etherboot (on x86), mkinitrd-net, terminal-server, dhcp-server -# clusternfs, tftp-server -# -# Tasks: -# 1) creation/management of boot images (kernel+initrd, etherboot enabled) -# mkinitrd-net is the command line interface for this -# 2) create/modify /etc/dhcpd.conf for diskless clients -# 3) create/modify /etc/exports for clusternfs export of "/" -# 4) add/remove entries in /etc/shadow$$CLIENTS$$ to allow user access -# 5) per client XF86Config-4, using /etc/XF86Config-4$$IP-ADDRESS$$ -# 6) other per client customizations (modules.conf, keyboard, mouse) -# 7) enable/modify /etc/xinetd.d/tftp for etherboot -# 8) create etherboot floppies for client machines -# -# Thanks to the fine work of the folks involved in ltsp.org, and -# Michael Brown <mbrown@fensystems.co.uk> -# - -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 Config; -use POSIX; - -my $in = 'interactive'->vnew('su'); - -my @buff; #- used to display status info - -my $central_widget; -my $window1; -my $windows; -my $status_box; -my $main_box; - -my $nfs_subnet; -my $nfs_mask; -my $thin_clients = 0; -my $cfg_dir = "/etc/drakxtools/draktermserv/"; -my $cfg_file = $cfg_dir . "draktermserv.conf"; -my $server_ip = get_ip_from_sys(); - -#- make sure terminal server and friends are installed -my $ts = system("rpm -qa | grep terminal-server > /dev/null"); -if ($ts == 256) { - if ($ENV{DISPLAY}) { - system("urpmi --X terminal-server > /dev/null"); - } else { - system("urpmi terminal-server > /dev/null"); - } - $ts = system("rpm -qa | grep terminal-server > /dev/null"); - if ($ts == 256) { - warn("Useless without Terminal Server"); - exit(1); - } -} - -if ("@ARGV" =~ /--enable/) { - my $cmd_line = 1; - enable_ts($cmd_line); - exit(0); -} - -if ("@ARGV" =~ /--disable/) { - my $cmd_line = 1; - disable_ts($cmd_line); - exit(0); -} - -if ("@ARGV" =~ /--start/) { - my $cmd_line = 1; - start_ts($cmd_line); - exit(0); -} - -if ("@ARGV" =~ /--stop/) { - my $cmd_line = 1; - stop_ts($cmd_line); - exit(0); -} - -if ("@ARGV" =~ /--adduser/) { - die "$0 $ARGV[0] requires a username...\n" if $#ARGV < 1; - my $cmd_line = 1; - adduser($cmd_line, $ARGV[1]); - exit(0); -} - -if ("@ARGV" =~ /--deluser/) { - die "$0 $ARGV[0] requires a username...\n" if $#ARGV < 1; - my $cmd_line = 1; - deluser($cmd_line, $ARGV[1]); - exit(0); -} - -if ("@ARGV" =~ /--addclient/) { - die "$0 $ARGV[0] requires hostname, MAC address, IP, nbi-image, 0/1 for THIN_CLIENT...\n" if $#ARGV < 5; - my $cmd_line = 1; - addclient($cmd_line, $ARGV[1], $ARGV[2], $ARGV[3], $ARGV[4], $ARGV[5]); - exit(0); -} - -if ("@ARGV" =~ /--delclient/) { - die "$0 $ARGV[0] requires hostname...\n" if $#ARGV < 1; - my $cmd_line = 1; - delclient($cmd_line, $ARGV[1]); - exit(0); -} - -read_conf_file(); -interactive_mode() if $#ARGV < 1; - -sub read_conf_file() { - if (-e $cfg_file) { - local *CONF_FILE; - open(CONF_FILE, "<" . $cfg_file) || print "You must be root to read configuration file. \n"; - local $_; - while (<CONF_FILE>) { - if (/^\bALLOW_THIN\b/) { - $thin_clients = 1; - last; - } - } - } -} - -sub write_conf_file() { - my @cfg_list; - if ($thin_clients == 1) { - @cfg_list = "ALLOW_THIN\n"; - } - output_p($cfg_file, @cfg_list); - chmod(0600, $cfg_file); -} - -sub write_thin_inittab { - my ($client_ip) = @_; - - my $inittab = " -# /etc/inittab\$\$IP=$client_ip\$\$ -# 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 = "/etc/inittab\$\$IP=$client_ip\$\$"; - local *INITTAB; - open(INITTAB, "> $inittab_file") or warn("Can't open $inittab_file!"); - print INITTAB $inittab; - close INITTAB -} - -sub cursor_wait() { - # turn the cursor to a watch - $window1->{rwindow}->window->set_cursor(new Gtk2::Gdk::Cursor("GDK_WATCH")); - gtkflush(); -} - -sub cursor_norm() { - # restore normal cursor - $window1->{rwindow}->window->set_cursor(new Gtk2::Gdk::Cursor("GDK_LEFT_PTR")); - gtkflush(); -} - -sub display_error { - my ($message) = @_; - my $error_box; - $$central_widget->destroy(); - gtkpack($status_box, - $error_box = gtkpack_(new Gtk2::VBox(0,0), - 1, new Gtk2::Label($message), - 0, gtkadd(gtkset_layout(new Gtk2::HButtonBox, 'spread'), - gtksignal_connect(new Gtk2::Button(N("OK")), clicked => sub { - $$central_widget->destroy(); - }), - ), - ) - ); - $central_widget = \$error_box; -} - -sub interactive_mode() { - $window1 = ugtk2->new('drakTermServ'); - $window1->{rwindow}->signal_connect(delete_event => sub { ugtk2->exit(0) }); - unless ($::isEmbedded) { - $window1->{rwindow}->set_position('center'); - $window1->{rwindow}->set_title(N("Mandrake Terminal Server Configuration")); - } - $window1->{rwindow}->set_border_width(5); - - gtkadd($window1->{window}, - gtkpack_(new Gtk2::VBox(0,2), - if_(!$::isEmbedded, 0, gtkcreate_img("drakTS.620x57")), - 1, gtkpack_(new Gtk2::HBox(0,2), - 1, gtkpack_(new Gtk2::VBox(0,2), - 1, gtkpack($status_box = new Gtk2::VBox(0,5), - $main_box = new Gtk2::VBox(0,10), - ), - 1, gtkpack_(new Gtk2::HBox(0,2), - 0, gtkadd(gtkset_layout(Gtk2::VButtonBox->new(), 'end'), - gtksignal_connect(new Gtk2::Button(N("Enable Server")), clicked => sub { - $$central_widget->destroy(); - $windows = 1; - cursor_wait(); - enable_ts(); - cursor_norm(); - }), - gtksignal_connect(new Gtk2::Button(N("Disable Server")), clicked => sub { - $$central_widget->destroy(); - cursor_wait(); - disable_ts(); - cursor_norm(); - }), - ), - 0, gtkadd(gtkset_layout(Gtk2::VButtonBox->new(), 'end'), - gtksignal_connect(new Gtk2::Button(N("Start Server")), clicked => sub { - $$central_widget->destroy(); - $windows = 0; - cursor_wait(); - start_ts(); - cursor_norm(); - }), - gtksignal_connect(new Gtk2::Button(N("Stop Server")), clicked => sub { - $$central_widget->destroy(); - cursor_wait(); - stop_ts(); - cursor_norm(); - }), - ), - 0, gtkadd(gtkset_layout(Gtk2::VButtonBox->new(), 'end'), - gtksignal_connect(new Gtk2::Button(N("Etherboot Floppy/ISO")), clicked => sub { - $$central_widget->destroy(); - $windows = 1; - make_boot(); - }), - gtksignal_connect(new Gtk2::Button(N("Net Boot Images")), clicked => sub { - $$central_widget->destroy(); - make_nbi(); - }), - ), - 0, gtkadd(gtkset_layout(Gtk2::VButtonBox->new(), 'end'), - gtksignal_connect(new Gtk2::Button(N("Add/Del Users")), clicked => sub { - $$central_widget->destroy(); - $windows = 0; - maintain_users(); - }), - gtksignal_connect(new Gtk2::Button(N("Add/Del Clients")), clicked => sub { $$central_widget->destroy(); maintain_clients() }), - ), - 1, new Gtk2::HBox(0,2), - 0, gtkadd(gtkset_layout(Gtk2::VButtonBox->new(), 'end'), - gtksignal_connect(new Gtk2::Button(N("Help")),clicked => sub { - $$central_widget->destroy(); - help(); - }), - gtksignal_connect(new Gtk2::Button(N("Close")), clicked => sub { - write_conf_file(); - Gtk2->main_quit(); - }), - ), - ), - ), - ), - ), - ); - $central_widget = \$main_box; - $window1->{rwindow}->show_all; - $window1->{rwindow}->realize; - $window1->{rwindow}->show_all(); - - $window1->main; - ugtk2->exit(0); -} - -sub about() { - text_view(N(" - Copyright (C) 2002 by MandrakeSoft - Stew Benedict sbenedict\@mandrakesoft.com - -") . $::license . N(" - - Thanks: - - LTSP Project http://www.ltsp.org - - Michael Brown <mbrown\@fensystems.co.uk> - -")); -} - -sub text_view { - my ($text) = @_; - my $box; - gtkpack($status_box, - $box = gtkpack_(new Gtk2::VBox(0,10), - 1, gtkpack_(new Gtk2::HBox(0,0), - 1, create_scrolled_window(gtktext_insert( -# gtkset_editable( - new Gtk2::TextView, -# 1) - [ [ $text ] ]) - ), - ), - 0, gtkadd(gtkset_layout(new Gtk2::HButtonBox, 'spread'), - gtksignal_connect(new Gtk2::Button(N("OK")), clicked => - sub { $$central_widget->destroy() }), - ), - ) - ); - $central_widget = \$box; - $status_box->show_all(); -} - -sub help() { - text_view(N("drakTermServ Overview - - - 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 drakTermServ is just a graphical interface - to help manage/customize these images. - - - 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. drakTermServ 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: - - 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\"; - } - - 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 ClusterNFS provides. - - Note: The \"#type\" entry is only used by drakTermServ. 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, /etc/inittab\$\$IP=client_ip\$\$ 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: You must stop/start the server after adding or changing clients. - - - Maintain /etc/exports: - Clusternfs allows export of the root filesystem to diskless clients. drakTermServ - sets up the correct entry to allow anonymous access to the root filesystem from - diskless clients. - - A typical exports entry for clusternfs is: - - / (ro,all_squash) - /home SUBNET/MASK(rw,root_squash) - - With SUBNET/MASK being defined for your network. - - - Maintain /etc/shadow\$\$CLIENT\$\$: - For users to be able to log into the system from a diskless client, their entry in - /etc/shadow needs to be duplicated in /etc/shadow\$\$CLIENTS\$\$. drakTermServ helps - in this respect by adding or removing system users from this file. - - - Per client /etc/X11/XF86Config-4\$\$IP-ADDRESS\$\$: - Through clusternfs, each diskless client can have it's own unique configuration files - on the root filesystem of the server. In the future drakTermServ will help create these - files. - - - Per client system configuration files: - Through clusternfs, each diskless client can have it's own unique configuration files - on the root filesystem of the server. In the future, drakTermServ can help create files - such as /etc/modules.conf, /etc/sysconfig/mouse, /etc/sysconfig/keyboard on a per-client - basis. - - - /etc/xinetd.d/tftp: - drakTermServ 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 it's images. - - - Create etherboot floppies/CDs: - The diskless client machines need either ROM images on the NIC, or a boot floppy - or CD to initate the boot sequence. drakTermServ 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/lib/etherboot/boot1a.bin \\ - /usr/lib/etherboot/lzrom/3c509.lzrom > /dev/fd0 - - -")); -} - -sub make_boot() { - #- make a boot image on floppy or iso from etherboot images - my $boot_box; - my $rom_path = "/usr/lib/etherboot"; - my @nics = all("/usr/lib/etherboot/lzrom"); - my $list_nics = new Gtk2::List(); - my $nic; - - foreach (@nics) { - my $t = $_; - $list_nics->add(gtkshow(gtksignal_connect(new Gtk2::ListItem($t), - select => sub { $nic = $t }))); - } - $list_nics->set_selection_mode('single'); - - gtkpack($status_box, - $boot_box = gtkpack_(new Gtk2::VBox(0,10), - 0, gtkadd(new Gtk2::HBox(0,10), - new Gtk2::HBox(0,5), - create_scrolled_window($list_nics), - gtkadd(new Gtk2::VBox(1,10), - new Gtk2::HBox(0,20), - gtksignal_connect(new Gtk2::Button(N("Boot Floppy")), clicked => - sub { write_eb_image($nic, $rom_path, "floppy") }), - gtksignal_connect(new Gtk2::Button(N("Boot ISO")), clicked => - sub { write_eb_image($nic, $rom_path, "iso") }), - new Gtk2::HBox(0,20), - ), - new Gtk2::HBox(0,5), - ), - ), - ); - - $central_widget = \$boot_box; - $boot_box->show_all(); -} - -sub make_nbi() { - my $nbi_box; - my @kernels = grep { /vmlinuz/ } all("/boot"); - my $kernel; - my $nic; - - #- just a static list for the moment - #- method in mknbi-net is much better - my @nics = ("3c509", "3c59x", "3c90x", "8139cp", "8139too", "acenic", "airo", - "aironet4500_card", "bcm5700", "dgrs", "dl2k", "dmfe", "e100", - "e1000", "eepro100", "epic100", "fealnx", "hamachi", "hp100", - "hysdn", "natsemi", "natsemi_old", "ne", "ne2k-pci", "ns83820", - "pcnet32", "prism2_pci", "prism2_plx", "rcpci", "sis900", - "starfire", "sundance", "sungem", "sunhme", "tlan", "tulip-old", - "via-rhine", "winbond-840", "xircom_cb", "xircom_tulip_cb", "yellowfin"); - - #- kernel/module info in tree view - my $model = Gtk2::TreeStore->new(Gtk2::GType->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 = Gtk2::TreeIter->new; - $model->append($t_kernel, undef); - $model->set($t_kernel, [ 0 => $_ ]); - my $k_detail = Gtk2::TreeIter->new; - foreach (@nics) { - $model->append($k_detail, $t_kernel); - $model->set($k_detail, [ 0 => $_ ]); - } - $k_detail->free; - } - - $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(Gtk2::GType->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 @nbis = grep { /\.nbi/ } all("/var/lib/tftpboot"); - my $nbi; - my $iter = Gtk2::TreeIter->new; - my $nbi_iter; - - foreach (@nbis) { - $list_model->append($iter); - $list_model->set($iter, [ 0 => $_ ]); - } - - $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; - }); - - gtkpack($status_box, - $nbi_box = gtkpack_(new Gtk2::VBox(1,10), - 0, gtkadd(new Gtk2::HBox(0,10), - create_scrolled_window($tree_kernels), - gtkadd(new Gtk2::VBox(1,10), - gtksignal_connect(new Gtk2::Button(N("Build Whole Kernel -->")), clicked => - sub { if ($kernel) { - $in->ask_warn('', N("This will take a few minutes.")); - cursor_wait(); - system("/usr/bin/mknbi-set -k /boot/$kernel"); - $list_model->clear; - @nbis = grep { /\.nbi/ } all("/var/lib/tftpboot"); - foreach (@nbis) { - $list_model->append($iter); - $list_model->set($iter, [ 0 => $_ ]); - } - cursor_norm(); - } else { - $in->ask_warn('', N("No kernel selected!")) if !($kernel); - } - }), - gtksignal_connect(new Gtk2::Button(N("Build Single NIC -->")), clicked => - sub { if ($nic) { - system("/usr/bin/mknbi-set -k /boot/$kernel -r $nic"); - $list_model->clear; - @nbis = grep { /\.nbi/ } all("/var/lib/tftpboot"); - foreach (@nbis) { - $list_model->append($iter); - $list_model->set($iter, [ 0 => $_ ]); - } - } else { - $in->ask_warn('', N("No NIC selected!")); - } - }), - gtksignal_connect(new Gtk2::Button(N("Build All Kernels -->")), clicked => sub { - $in->ask_warn('', N("This will take a few minutes.")); - cursor_wait(); - system("/usr/bin/mknbi-set"); - $list_model->clear; - @nbis = grep { /\.nbi/ } all("/var/lib/tftpboot"); - foreach (@nbis) { - $list_model->append($iter); - $list_model->set($iter, [ 0 => $_ ]); - } - cursor_norm(); - }), - new Gtk2::HBox(1,1), - gtksignal_connect(new Gtk2::Button(N("<-- Delete")), clicked => - sub { my $nbi = "/var/lib/tftpboot/" . $nbi; - my $result = unlink($nbi) || warn("Can't delete $nbi..."); - if ($result == 1) { - $list_model->remove($nbi_iter); - } - }), - gtksignal_connect(new Gtk2::Button(N("Delete All NBIs")), clicked => - sub { cursor_wait(); - foreach (grep { /\.nbi/ } all("/var/lib/tftpboot")) { - my $nbi = "/var/lib/tftpboot/" . $_; - unlink($nbi) || warn("Can't delete $nbi..."); - } - $list_model->clear; - cursor_norm(); - }), - new Gtk2::HBox(1,1), - ), - create_scrolled_window($list_nbis), - ),), - ); - - $central_widget = \$nbi_box; - $nbi_box->show_all(); -} - -sub maintain_users() { - #- copy users from /etc/shadow to /etc/shadow$$CLIENT$$ to allow ts login - my $user_box; - my @sys_users = cat_("/etc/shadow"); - my @ts_users = cat_("/etc/shadow\$\$CLIENT\$\$"); - - #- use /homes to filter system daemons - my @homes = all("/home"); - - my $list_model = Gtk2::ListStore->new(Gtk2::GType->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 $iter = Gtk2::TreeIter->new; - my $sys_user; - - foreach (@sys_users) { - my ($s_label) = split(/:/, $_, 2); - if (grep { /$s_label/ } @homes) { - $list_model->append($iter); - $list_model->set($iter, [ 0 => $s_label ]); - } - } - $iter->free; - - $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(Gtk2::GType->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); - - $iter = Gtk2::TreeIter->new; - 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($iter); - $list_model->set($iter, [ 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); - }); - - gtkpack($status_box, - $user_box = gtkpack_(new Gtk2::VBox(0,10), - 0, gtkadd(new Gtk2::Label(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(new Gtk2::HBox(0,20), - create_scrolled_window($list_sys_users), - gtkadd(new Gtk2::VBox(1,10), - new Gtk2::HBox(0,10), - gtksignal_connect(new Gtk2::Button(N("Add User -->")), clicked => - sub { my $result = adduser(0, $sys_user); - if ($result == 0) { - $list_model->append($iter); - $list_model->set($iter, [ 0 => $sys_user ]); - } - }), - gtksignal_connect(new Gtk2::Button(N("<-- Del User")), clicked => - sub { deluser(0, $ts_user); - $list_model->remove($iter); - }), - new Gtk2::HBox(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; - - #- client info in tree view - my $model = Gtk2::TreeStore->new(Gtk2::GType->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 = Gtk2::TreeIter->new; - $model->append($t_client, undef); - $model->set($t_client, [ 0 => $key ]); - - my $c_detail = Gtk2::TreeIter->new; - - $model->append($c_detail, $t_client); - $model->set($c_detail, [ 0 => $clients{$key}{hardware} ]); - - $model->append($c_detail, $t_client); - $model->set($c_detail, [ 0 => $clients{$key}{address} ]); - - $model->append($c_detail, $t_client); - $model->set($c_detail, [ 0 => N("type: %s", $clients{$key}{type}) ]); - - if ($clients{$key}{filename}) { - $model->append($c_detail, $t_client); - $model->set($c_detail, [ 0 => $clients{$key}{filename} ]); - } - } - - $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 { - $client = ''; - } - }); - - #- entry boxes for client data entry - my $label_host = new Gtk2::Label("Client Name:"); - $label_host->set_justify('left'); - my $entry_host = new Gtk2::Entry(); - my $label_mac = new Gtk2::Label("MAC Address:"); - $label_mac->set_justify('left'); - my $entry_mac = new Gtk2::Entry(); - my $label_ip = new Gtk2::Label("IP Address:"); - $label_ip->set_justify('left'); - my $entry_ip = new Gtk2::Entry(); - my $label_nbi = new Gtk2::Label("Kernel Netboot Image:"); - $label_nbi->set_justify('left'); - my $entry_nbi = new Gtk2::Combo(); - - my @images = grep { /\.nbi/ } all("/var/lib/tftpboot/"); - my $have_nbis = @images; - if ($have_nbis) { - unshift(@images, ""); - $entry_nbi->set_popdown_strings(@images); - } else { - $in->ask_warn('', N("No net boot images created!")); - make_nbi(); - return 1; - } - - my $check_thin; - my $check_allow_thin; - my $is_thin = 0; - - gtkpack($status_box, - $client_box = gtkpack_(new Gtk2::VBox(1,10), - 0, gtkadd(new Gtk2::HBox(0,5), - gtkadd(new Gtk2::VBox(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(new Gtk2::VBox(1,10), - gtkadd(new Gtk2::HBox(0,1), - gtksignal_connect($check_thin = new Gtk2::CheckButton(N("Thin Client")), clicked => - sub { invbool \$is_thin }), - $check_allow_thin = new Gtk2::CheckButton(N("Allow Thin Clients")), - ), -# new Gtk2::HBox(1,1), - gtksignal_connect(new Gtk2::Button(N("Add Client -->")), clicked => - sub { my $hostname = $entry_host->get_text(); - my $mac = $entry_mac->get_text(); - my $ip = $entry_ip->get_text(); - my $nbi = $entry_nbi->entry->get_text(); - if ($hostname && $mac && $ip) { - - my $result = addclient(0, $hostname, $mac, $ip, $nbi, $is_thin); - - if ($result == 0) { - my $t_client = Gtk2::TreeIter->new; - - $model->append($t_client, undef); - $model->set($t_client, [ 0 => $hostname ]); - - my $c_det_hw = Gtk2::TreeIter->new; - $model->append($c_det_hw, $t_client); - $model->set($c_det_hw, [ 0 => $mac ]); - - my $c_det_ip = Gtk2::TreeIter->new; - $model->append($c_det_ip, $t_client); - $model->set($c_det_ip, [ 0 => $ip ]); - - my $client_type = "type: fat"; - $client_type = "type: thin" if $is_thin == 1; - my $c_det_type = Gtk2::TreeIter->new; - $model->append($c_det_type, $t_client); - $model->set($c_det_type, [ 0 => $client_type ]); - - if ($nbi) { - my $c_det_nbi = Gtk2::TreeIter->new; - $model->append($c_det_nbi, $t_client); - $model->set($c_det_nbi, [ 0 => $nbi ]); - } - $check_thin->set_active(0); - $is_thin = 0; - } - } - }), - gtksignal_connect(new Gtk2::Button(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 $result = delclient(0, $client); - if ($result == 0) { - $model->remove($citer); - } - }), - gtksignal_connect(new Gtk2::Button(N("Delete Client")), clicked => - sub { my $result = delclient(0, $client); - if ($result == 0) { - $model->remove($citer); - } - }), - gtksignal_connect(new Gtk2::Button(N("dhcpd Config...")), clicked => - sub { $$central_widget->destroy(); dhcpd_config() }), -# new Gtk2::HBox(1,1), - ), - create_scrolled_window($tree_clients), - ),), - ); - - $check_allow_thin->set_active($thin_clients); - $check_thin->set_sensitive($thin_clients); - gtksignal_connect($check_allow_thin, clicked => - sub { invbool \$thin_clients; - $check_thin->set_sensitive($thin_clients); - # 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 - if ($thin_clients == 1) { - 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 doesn't work - x11 doesn't help either - update_hosts_allow("enable"); - } else { - 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"); - } - $in->ask_warn('', N("Need to restart the Display Manager for full changes to take effect. \n(service dm restart - at the console)")); - } - ); - $central_widget = \$client_box; - $client_box->show_all(); -} - -sub dhcpd_config() { - #- do main dhcp server config - my $dhcpd_box; - my @ifvalues; - my @resolve; - my %netconfig; - my @nservers; - - #- entry boxes for data entry - my $box_subnet = new Gtk2::HBox(0,0); - my $label_subnet = new Gtk2::Label(N("Subnet:")); - $label_subnet->set_justify('right'); - my $entry_subnet = new Gtk2::Entry(20); - $box_subnet->pack_end($entry_subnet, 0, 0, 10); - $box_subnet->pack_end($label_subnet, 0, 0, 10); - - my $box_netmask = new Gtk2::HBox(0,0); - my $label_netmask = new Gtk2::Label(N("Netmask:")); - $label_netmask->set_justify('left'); - my $entry_netmask = new Gtk2::Entry(20); - $box_netmask->pack_end($entry_netmask, 0, 0, 10); - $box_netmask->pack_end($label_netmask, 0, 0, 10); - - my $box_routers = new Gtk2::HBox(0,0); - my $label_routers = new Gtk2::Label(N("Routers:")); - $label_routers->set_justify('left'); - my $entry_routers = new Gtk2::Entry(20); - $box_routers->pack_end($entry_routers, 0, 0, 10); - $box_routers->pack_end($label_routers, 0, 0, 10); - - my $box_subnet_mask = new Gtk2::HBox(0,0); - my $label_subnet_mask = new Gtk2::Label(N("Subnet Mask:")); - $label_subnet_mask->set_justify('left'); - my $entry_subnet_mask = new Gtk2::Entry(); - $box_subnet_mask->pack_end($entry_subnet_mask, 0, 0, 10); - $box_subnet_mask->pack_end($label_subnet_mask, 0, 0, 10); - - my $box_broadcast = new Gtk2::HBox(0,0); - my $label_broadcast = new Gtk2::Label(N("Broadcast Address:")); - $label_broadcast->set_justify('left'); - my $entry_broadcast = new Gtk2::Entry(20); - $box_broadcast->pack_end($entry_broadcast, 0, 0, 10); - $box_broadcast->pack_end($label_broadcast, 0, 0, 10); - - my $box_domain = new Gtk2::HBox(0,0); - my $label_domain = new Gtk2::Label(N("Domain Name:")); - $label_domain->set_justify('left'); - my $entry_domain = new Gtk2::Entry(20); - $box_domain->pack_end($entry_domain, 0, 0, 10); - $box_domain->pack_end($label_domain, 0, 0, 10); - - my $box_name_servers = new Gtk2::HBox(0,0); - my $box_name_servers_entry = new Gtk2::VBox(0,0); - my $label_name_servers = new Gtk2::Label(N("Name Servers:")); - $label_name_servers->set_justify('left'); - my $entry_name_server1 = new Gtk2::Entry(); - my $entry_name_server2 = new Gtk2::Entry(); - my $entry_name_server3 = new Gtk2::Entry(); - $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, 10); - $box_name_servers->pack_end($label_name_servers, 0, 0, 10); - - my $label_ip_range_start = new Gtk2::Label(N("IP Range Start:")); - my $label_ip_range_end = new Gtk2::Label(N("IP Range End:")); - my $entry_ip_range_start = new Gtk2::Entry(); - my $entry_ip_range_end = new Gtk2::Entry(); - - #- 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]); - - gtkpack($status_box, - $dhcpd_box = gtkpack_(new Gtk2::HBox(1,10), - 0, gtkadd((new Gtk2::VBox), - 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(new Gtk2::VBox(0,0), - new Gtk2::Label(N("dhcpd Server Configuration") . "\n\n" . - N("Most of these values were extracted\nfrom your running system.\nYou can modify as needed.")), - new Gtk2::HSeparator, - gtkadd((new Gtk2::HBox), - new Gtk2::Label(N("Dynamic IP Address Pool:")), - ), - gtkadd((new Gtk2::HBox(0,0)), - gtkadd((new Gtk2::VBox), - gtkadd($label_ip_range_start), - gtkadd($entry_ip_range_start), - ), - gtkadd((new Gtk2::VBox), - gtkadd($label_ip_range_end), - gtkadd($entry_ip_range_end), - ), - ), - gtkadd(new Gtk2::HBox), - gtksignal_connect(new Gtk2::Button(N("Write Config")), clicked => - sub { write_dhcpd_config( - $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(), - ) }), - new Gtk2::HBox(0,10), - ), - ), - ); - - $central_widget = \$dhcpd_box; - $dhcpd_box->show_all(); -} - -sub get_mask_from_sys() { - my %netconfig; - if (-e "/etc/sysconfig/network-scripts/ifcfg-eth0") { - %netconfig = getVarsFromSh("/etc/sysconfig/network-scripts/ifcfg-eth0"); - $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 eth0`; - my @ifvalues = split(/[: \t]+/, $ifconfig[0]); - - $ifvalues[5]; -} - -sub get_ip_from_sys() { - my @ifconfig = grep { /inet/ } `/sbin/ifconfig eth0`; - my @ifvalues = split(/[: \t]+/, $ifconfig[0]); - - $ifvalues[3]; -} - -sub write_dhcpd_config { - my ($subnet, $netmask, $routers, $subnet_mask, $broadcast, $domain, $ns1, $ns2, $ns3, $pool_start, $pool_end) = @_; - - $nfs_subnet = $subnet; - $nfs_mask = $subnet_mask; - - local *FHANDLE; - open(FHANDLE, "> /etc/dhcpd.conf"); - print FHANDLE "#dhcpd.conf - generated by drakTermServ\n\n"; - print FHANDLE "ddns-update-style none;\n\n"; - print FHANDLE "# Long leases (48 hours)\ndefault-lease-time 172800;\nmax-lease-time 172800;\n\n"; - print FHANDLE "# Include Etherboot definitions and defaults\ninclude \"/etc/dhcpd.conf.etherboot.include\";\n\n"; - print FHANDLE "# Network-specific section\n\n"; - - print FHANDLE "subnet $subnet netmask $netmask {\n"; - print FHANDLE "\toption routers $routers;\n" if $routers; - print FHANDLE "\toption subnet-mask $subnet_mask;\n" if $subnet_mask; - print FHANDLE "\toption broadcast-address $broadcast;\n" if $broadcast; - print FHANDLE "\toption domain-name \"$domain\";\n" if $domain; - - my $pool_string = "\trange dynamic-bootp " . $pool_start . " " . $pool_end . ";\n" if $pool_start && $pool_end; - print FHANDLE $pool_string if $pool_string; - - my $ns_string = "\toption domain-name-servers " . $ns1 if $ns1; - $ns_string = $ns_string . ", " . $ns2 if $ns2; - $ns_string = $ns_string . ", " . $ns3 if $ns3; - $ns_string = $ns_string . ";\n" if $ns_string; - print FHANDLE $ns_string if $ns_string; - - print FHANDLE "}\n\n"; - - print FHANDLE "# Include client machine configurations\ninclude \"/etc/dhcpd.conf.etherboot.clients\";\n"; - close FHANDLE -} - -sub write_eb_image { - #- write a bootable etherboot CD image or floppy - my ($nic, $rom_path, $type) = @_; - 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 = system("cat $rom_path/boot1a.bin $rom_path/lzrom/$nic > /dev/fd0") if $result; - if ($result) { - $in->ask_warn('', N("Couldn't access the floppy!")) - } else { - $in->ask_warn('', N("Floppy can be removed now")) - } - } else { - $in->ask_warn('', N("No floppy drive available!")); - } - } else { - mkdir_p("/tmp/eb"); - system("cat $rom_path/boot1a.bin $rom_path/lzrom/$nic > /tmp/eb/eb.img"); - system("dd if=/dev/zero of=/tmp/eb/eb.img bs=512 seek=72 count=2808"); - system("mkisofs -b eb.img -o /tmp/$nic.iso /tmp/eb"); - rm_rf("/tmp/eb"); - if (-e "/tmp/$nic.iso") { - $in->ask_warn('', N("Etherboot ISO image is %s", "/tmp/$nic.iso")) - } else { - $in->ask_warn('', N("Something went wrong! - Is mkisofs installed?")) - } - } -} - -sub enable_ts { - #- setup default config files for terminal server - - my $cmd_line = @_; - - @buff = (); - $buff[0] = "Enabling Terminal Server...\n\n"; - $buff[1] = "\tChecking default /etc/dhcpd.conf...\n"; - my @my_conf = cat_("/etc/dhcpd.conf"); - if ($my_conf[0] !~ /drakTermServ/) { - if ($cmd_line == 1) { - print("No /etc/dhcpd.conf built yet - use GUI to create!!\n"); - return; - } else { - $in->ask_warn('', N("Need to create /etc/dhcpd.conf first!")); - #$central_widget->destroy; - dhcpd_config(); - return; - } - } - 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"; - local *FHANDLE; - open(FHANDLE, "> /etc/exports"); - print FHANDLE "#/etc/exports - generated by drakTermServ\n\n"; - print FHANDLE "/\t(ro,all_squash)\n"; - if ($nfs_subnet eq '') { - $nfs_subnet = get_subnet_from_sys(); - $nfs_mask = get_mask_from_sys(); - my $sys_broadcast = get_broadcast_from_sys(); - $nfs_subnet = get_subnet_from_sys($sys_broadcast, $nfs_mask); - - } - print FHANDLE "/home\t$nfs_subnet/$nfs_mask(rw,root_squash)\n"; - close FHANDLE; - $buff_index = toggle_chkconfig("on", "clusternfs", $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 - my $cmd_line = @_; - - @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"; - 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", "clusternfs", $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) = @_; - system("/sbin/chkconfig $service $state"); - $buff[$buff_index] = "\tTurning $service $state...\n"; - $buff_index++; - $buff_index; -} - -sub service_change { - my ($service, $command, $buff_index) = @_; - system("BOOTUP=serial /sbin/service $service $command > /tmp/drakTSservice.status 2>&1"); - local *STATUS; - open(STATUS, "/tmp/drakTSservice.status"); - local $_; - while (<STATUS>) { - $buff[$buff_index] = "\t$_"; - $buff_index++; - } - close STATUS; - unlink "/tmp/drakTSservice.status" or warn("Can't delete /tmp/drakTSservice.status\n"); - $buff_index; -} - -sub start_ts { - #- start the terminal server - my $cmd_line = @_; - - @buff = (); - $buff[0] = "Starting Terminal Server...\n\n"; - my $buff_index = service_change("dhcpd", "start", 2); - $buff_index = service_change("clusternfs", "start", $buff_index); - $buff[$buff_index] = "\n\tDone!"; - - if ($cmd_line == 1) { - print "@buff\n"; - return; - } - - show_status(@buff); -} - -sub stop_ts { - #- stop the terminal server - my $cmd_line = @_; - - @buff = (); - $buff[0] = "Stopping Terminal Server...\n\n"; - my $buff_index = service_change("dhcpd", "stop", 2); - $buff_index = service_change("clusternfs", "stop", $buff_index); - $buff[$buff_index] = "\n\tDone!"; - - if ($cmd_line == 1) { - print "@buff\n"; - return; - } - - show_status(@buff); - -} - -sub show_status() { - text_view("@buff"); -} - -sub adduser { - my ($cmd_line, $username) = @_; - my @active_users = cat_("/etc/shadow"); - my @ts_users = cat_("/etc/shadow\$\$CLIENT\$\$"); - my $is_user = grep { /$username/ } @active_users; - my $add_fail = 0; - my $in_already; - - if ($is_user) { - my @shadow_entry = grep { /$username/ } @active_users; - my $is_ts_user = grep { /$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 "$username passwd bad in Terminal Server - rewriting...\n"; - deluser($cmd_line, $username); - adduser($cmd_line, $username); - } - } else { - # new ts user - local *FHANDLE; - open(FHANDLE, ">> /etc/shadow\$\$CLIENT\$\$"); - print FHANDLE $shadow_entry[0] or $add_fail = 1; - close FHANDLE; - $in_already = 0; - } - } - - if ($cmd_line == 1) { - print "$username is not a user..\n" if !($is_user); - print "$username is already a Terminal Server user\n" if $in_already; - if ($add_fail == 1 || $in_already || !$is_user) { - print "Addition of $username to Terminal Server failed!\n"; - } else { - print "$username added to Terminal Server\n"; - } - return; - } else { - $in_already; - } -} - -sub deluser { - # del a user from the shadow$$CLIENT$$ file - my ($cmd_line, $username) = @_; - my $i; - my $user_deleted; - - my @ts_users = cat_("/etc/shadow\$\$CLIENT\$\$"); - my $is_ts_user = grep { /$username/ } @ts_users; - - if ($is_ts_user) { - $i = 0; - foreach my $user (@ts_users) { - if ($user =~ /$username/) { - splice(@ts_users, $i, 1); - $user_deleted = 1; - last; - } - $i++; - } - local *FHANDLE; - open(FHANDLE, "> /etc/shadow\$\$CLIENT\$\$"); - print FHANDLE $_ foreach @ts_users; - close FHANDLE; - } - - if ($cmd_line == 1) { - if ($user_deleted) { - print "Deleted $username...\n"; - } else { - print "$username not found...\n"; - } - return; - } -} - -sub addclient { - #- add a new client entry after checking for dups - my ($cmd_line, $hostname, $mac, $ip, $nbi, $is_thin) = @_; - - 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 "$hostname already in use\n" if $host_in_use; - print "$mac already in use\n" if $mac_in_use; - print "$ip already in use\n" 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; - - my $clients = "/etc/dhcpd.conf.etherboot.clients"; - local *CLIENT; - open(CLIENT, ">> $clients") or warn("Can't open $clients!"); - my $client_entry = format_client_entry($hostname, %ts_clients); - print CLIENT $client_entry; - close CLIENT; - 0; - } -} - -sub delclient { - #- find a client and delete the entry in dhcpd.conf - my ($cmd_line, $hostname) = @_; - my $host_found; - - my %ts_clients = read_dhcpd_conf(); - - foreach my $client (keys(%ts_clients)) { - if ($hostname eq $client) { - $host_found = 1; - delete $ts_clients{$client}; - write_dhcpd_conf(%ts_clients); - return 0; - } - } - - if ($cmd_line == 1) { - print "$hostname not found...\n" 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 don't 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 $ip = get_ip_from_sys(); - my @values = split(/\./, $ip); - my $subnet = $values[0] . "." . $values[1] . "." . $values[2] . "."; - my $i; - if ($mode eq "enable") { - my $has_all = `grep ALL /etc/hosts.allow`; - if ($has_all) { - $in->ask_warn('', 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\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 = "host $client {\n"; - $entry .= "\thardware ethernet\t$ts_clients{$client}{hardware};\n"; - $entry .= "\tfixed-address\t\t$ts_clients{$client}{address};\n"; - $entry .= "\t#type\t\t\t$ts_clients{$client}{type};\n" if $ts_clients{$client}{type}; - $entry .= "\tfilename\t\t\"$ts_clients{$client}{filename}\";\n" if $ts_clients{$client}{filename}; - $entry .= "}\n"; - write_thin_inittab($ts_clients{$client}{address}) if $ts_clients{$client}{type} eq "thin"; - $entry -} - -sub write_dhcpd_conf { - my %ts_clients = @_; - my $clients = "/etc/dhcpd.conf.etherboot.clients"; - - local *CLIENT; - open(CLIENT, "> $clients") or warn("Can't open $clients!"); - foreach my $key (keys(%ts_clients)) { - my $client_entry = format_client_entry($key, %ts_clients); - print CLIENT $client_entry; - } - close CLIENT -} - -sub read_dhcpd_conf() { - my $clients = "/etc/dhcpd.conf.etherboot.clients"; - my %ts_clients; - my $hostname; - - #- read and parse current client entries - local *CLIENTS; - open(CLIENTS, $clients) or warn("Can't open $clients\n"); - while (<CLIENTS>) { - 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/; - $ts_clients{$hostname}{$name} = $val; - } - } - } - close CLIENTS; - %ts_clients; -} |