diff options
Diffstat (limited to 'samba_wizard')
-rwxr-xr-x | samba_wizard/Samba.pm | 517 |
1 files changed, 468 insertions, 49 deletions
diff --git a/samba_wizard/Samba.pm b/samba_wizard/Samba.pm index a72578e0..f310fcb2 100755 --- a/samba_wizard/Samba.pm +++ b/samba_wizard/Samba.pm @@ -28,59 +28,203 @@ use MDK::Wizard::Wizcommon; my $wiz = new MDK::Wizard::Wizcommon; my $o = { - name => 'configuration wizard', + name => 'Samba wizard', var => { - ip1 => '', - ip2 => '' - } + wiz_box_list => '', + wiz_hosts_allow => '', + wiz_do_file_sharing => '', + wiz_all_printers => '', + wiz_level => '', + wiz_printers => '', + wiz_do_printer_sharing => '', + wiz_do_homes => '', + wiz_workgroup => '', + wiz_dir => '', + wiz_banner => '', + wiz_write_list => '', + wiz_read_list => '', + wiz_hosts_deny => '', + list_printers => '' + }, + needed_rpm => [ 'samba-server' ], + defaultimage => "$ENV{__WIZ_HOME__}samba_wizard/images/samba.png" }; +my $old = read_conf("/etc/samba/smb.conf"); + +my %level = ( + 1 => N('All - No access restriction'), + 2 => N('My rules - Ask me allowed and denied hosts') +); + $o->{pages} = { - welcome => { - name => N('') . "\n\n" . N('') . "\n\n" . N(''), - no_back => 1, - next => 'ip_range' - }, - confige => { - name => N('') . "\n\n" . N('') . "\n\n" . N(''), - pre => sub { - $o->{var}{ip1} ||= f1(); - $o->{var}{ip2} ||= f2(); - }, - post => \&check, - data => [ - { label => '' }, - { label => N(''), val => \$o->{var}{ip1} }, - { label => N(''), val => \$o->{var}{ip2} }, - ], - next => 'summary' - }, - warning => { - name => N('Warning.'), - data => [ { label => N('') } ], - next => 'summary' - }, - error => { - name => N('Error.'), - data => [ { label => N('') } ], - next => 'config' - }, - summary => { - name => N('') . "\n\n" . N('') . "\n\n" . N(''), - data => [ - { label => N(''), type => 'field', val => \$o->{var}{ip1} }, - { label => '' }, - { label => N(''), type => 'field', val => \$o->{var}{ip2} }, - ], - post => \&do_it, - next => 'end' - }, - end => { - name => N('Congratulation'), - data => [ { label => N('') } ], - end => 1, - next => 0 - }, + welcome => { + name => N('Samba Configuration Wizard') . "\n\n" . N('Samba allows your server to behave as a file and print server for workstations running non-Linux systems.') . "\n\n" . N('This wizard will help you configuring the Samba services of your server.'), + no_back => 1, + next => 'ask_workgroup' + }, + ask_workgroup => { + name => N('Workgroup') . "\n\n" . N('Samba needs to know the Windows Workgroup it will serve.') . "\n\n" . N('Samba needs to know the Windows Workgroup it will serve.'), + pre => sub { + $o->{var}{wiz_workgroup} ||= get_workgroup() + }, + data => [ + { label => N('Workgroup:'), val => \$o->{var}{wiz_workgroup} }, + ], + post => \&check_workgroup, + next => 'ask_banner' + }, + error_in_workgroup => { + name => N('Error.'), + data => [ + { label => N('The Workgroup is wrong') }, + ], + post => \&check_workgroup, + next => 'ask_workgroup' + }, + ask_banner => { + name => N('Server Banner.') . "\n\n" . N('The banner is the way this server will be described in the Windows workstations.') . "\n\n" . N('The banner is the way this server will be described in the Windows workstations.'), + pre => sub { + $o->{var}{wiz_banner} ||= get_banner() + }, + post => \&check_banner, + data => [ + { label => N('Banner:'), val => \$o->{var}{wiz_banner} }, + ], + next => 'ask_net' + }, + error_in_banner => { + name => N('Error.'), + data => [ + { label => N('The Server Banner is incorrect') }, + ], + next => 'ask_banner' + }, + ask_net => { + name => N('Access control') . "\n\n" . N('') . "\n\n" . N(''), + pre => sub { + $o->{var}{wiz_level} ||= 1 + }, + post => sub { return 'ask_netmask' if $o->{var}{wiz_level} == 2 }, + data => [ + { label => N('Access level :'), val => \$o->{var}{wiz_level}, list => [ keys %level ], format => sub { $level{$_[0]} } }, + ], + next => 'ask_services' + }, + ask_netmask => { + name => N('Access control') . "\n\n" . N('* Example 1: allow all IPs in 150.203.*.*; except one\nhosts allow = 150.203. EXCEPT 150.203.6.66') . "\n\n" . N('* Example 2: allow hosts that match the given network/netmask\nhosts allow = 150.203.15.0/255.255.255.0') . "\n\n" . N('* Example 3: allow a couple of hosts\nhosts allow = lapland, arvidsjaur') . "\n\n" . N('* Example 4: allow only hosts in NIS netgroup \qfoonet\q, but deny access from one particular host\nhosts allow = @foonet\nhosts deny = pirate') . "\n\n" . N('Note that access still requires suitable user-level passwords.'), + pre => sub { + $o->{var}{wiz_hosts_allow} ||= get_allow_host(); + $o->{var}{wiz_hosts_allow} ||= get_deny_host() + }, + post => \&check, + data => [ + { label => N('Allow hosts:'), val => \$o->{var}{wiz_allow_host} }, + { label => N('Deny hosts:'), val => \$o->{var}{wiz_deny_host} }, + ], + next => 'ask_services' + }, + ask_services => { + name => N('Enabled Samba Services') . "\n\n" . N('Samba can provide a common file sharing area to your Windows workstation, and can also provide printer sharing for the printers connected to your server.'), + pre => sub { + $o->{var}{wiz_do_file_sharing} ||= get_file_sharing(); + $o->{var}{wiz_do_printer_sharing} ||= 1; + $o->{var}{wiz_do_homes} ||= get_home_sharing() + }, + post => \&check_services, + data => [ + { text => N('Enable file sharing area'), type => 'bool', val => \$o->{var}{wiz_do_file_sharing} }, + { text => N('Enable Server Printer Sharing'), type => 'bool', val => \$o->{var}{wiz_do_printer_sharing} }, + { text => N('Make home directories available for their owners'), type => 'bool', val => \$o->{var}{wiz_do_homes} }, + ], + next => 'ask_dir' + }, + warn_smbpasswd => { + name => N('Warning.') . "\n\n" . N('You have selected to allow user access their home directories via samba but you/they must use smbpasswd to set a password.'), + post => \&ask_dir, + next => 'summary' + }, + ask_dir => { + name => N('Shared directory:') . "\n\n" . N('Type the path of the directory you want being shared.'), + pre => sub { + $o->{var}{wiz_dir} ||= get_dir() + }, + post => \&check_dir, + data => [ + { label => N('Shared directory:'), val => \$o->{var}{wiz_dir} }, + ], + next => 'ask_access' + }, + error_in_dir => { + name => N('Error.'), + data => [ + { label => N('The path you entered does not exist.') }, + ], + next => 'ask_dir' + }, + ask_access => { + name => N('File permissions') . "\n\n" . N('Type users or group separated by a comma (groups must be preceded by a \'@\') like this :\nroot, fred, @users, @wheel for each kind of permission.') . "\n\n" . N(''), + pre => sub { + $o->{var}{wiz_read_list} ||= get_read(); + $o->{var}{wiz_write_list} ||= get_write() + }, + post => \&check_users, + data => [ + { label => N('read list:'), help => N('root, fred, @users, @wheel'), val => \$o->{var}{wiz_read_list} }, + { label => N('write list:'), help => N('root, fred, @users, @wheel'), val => \$o->{var}{wiz_write_list} }, + ], + next => 'ask_printers' + }, + ask_printers => { + name => N('Select which printers you want to be accessible from known users'), + pre => sub { + $o->{var}{list_printers} ||= [ list_printers() ]; + $o->{var}{wiz_box_list} ||= [] + }, + post => \&check, + data => [ + { text => N('Enable all printers'), type => 'bool', val => \$o->{var}{wiz_all_printers} }, + { val => \$o->{var}{wiz_box_list}, boolean_list => \$o->{var}{list_printers}, disabled => sub { $o->{var}{wiz_all_printers} and return 1; 0 } }, + ], + next => 'summary' + }, + warning => { + name => N('Warning.'), + data => [ { label => N('') } ], + next => 'summary' + }, + error => { + name => N('Error.'), + data => [ { label => N('') } ], + next => 'config' + }, + summary => { + name => N('Configuring Samba') . "\n\n" . N('The wizard collected the following parameters +configure Samba.') . "\n\n" . N('To accept these values, and configure your server, click the Next button or use the Back button to correct them.'), + pre => sub { + $o->{var}{printers} = get_printers(); + $o->{var}{file_sharing} = $o->{var}{wiz_do_file_sharing} ? N("enabled") : N("disabled"); + $o->{var}{printer_sharing} = $o->{var}{wiz_do_printer_sharing} ? N("enabled") : N("disabled"); + $o->{var}{shared_homes} = $o->{var}{wiz_do_homes} ? N("enabled") : N("disabled") + }, + data => [ + { label => N('Workgroup:'), fixed_val => \$o->{var}{wiz_workgroup} }, + { label => N('Server Banner:'), fixed_val => \$o->{var}{wiz_banner} }, + { label => N('File Sharing:'), fixed_val => \$o->{var}{file_sharing} }, + { label => N('Shared directory:'), fixed_val => \$o->{var}{wiz_dir} }, + { label => N('Print Server:'), fixed_val => \$o->{var}{printer_sharing} }, + { label => N('Home:'), fixed_val => \$o->{var}{shared_homes} }, + { label => N('Printers:'), fixed_val => \$o->{var}{printers} }, + ], + post => \&do_it, + next => 'end' + }, + end => { + name => N('Congratulation'), + data => [ { label => N('The wizard successfully configured your Samba server.') } ], + end => 1, + next => 0 + }, }; sub new { @@ -90,4 +234,279 @@ sub new { }, $class; } +sub check { + $> and return 1; + $o->is_dhcp() and return 2; + 0; +} + +sub check_services { + $o->{var}{wiz_do_homes} and return 'warn_smbpasswd'; + $o->{var}{wiz_do_file_sharing} and return 'ask_dir'; + $o->{var}{wiz_do_printer_sharing} and return 'ask_printers'; +} + +sub check_dir { + -d ($o->{var}{wiz_dir}) or return 'error_in_dir' +} + +# the "__" before comment is to avoid conflicts with possible "comment" variable +# for variables value is in value key and comment idem (no risque of conflict) + +sub read_conf { + my $self = {}; + my ($file) = @_; + my $menu; + my @tab; + my %conf; + + open(FH, $file) or die "$! ($file)"; + while (<FH>) { + if (/^(\s*\;?\s*)\[(.*)\].*/) { + $menu = $2; + $conf{$menu}{__comment} = $1; + } + elsif (/^(?!\#)(\s*\;*\s*)(.*?)\s*=\s*(.*)\s*$/) { + $conf{$menu}{$2}{value} = $3; + $conf{$menu}{$2}{comment} = $1; + } + push @tab, $_; + } + $self->{conf} = \%conf; + $self->{tab} = \@tab; + bless $self; +} + +# we parse @tab to check for values in the struct. + +sub write_conf { + my $self = shift; + my ($file) = @_; + my $menu; + + open(FH, "> $file") or die "$!"; + foreach (@{$self->{tab}}) { + if (/^\s*\;?\s*\[(.*)\].*/) { + $menu = $1; + print FH "$self->{conf}->{$menu}{__comment}"."[$menu]\n"; + } + elsif (/^(?!\#)\s*\;*\s*(.*?)\s*=/) { + print FH "$self->{conf}->{$menu}{$1}{comment}"."$1" ." = ". "$self->{conf}->{$menu}{$1}{value}\n"; + } + else { + print FH $_; + } + } +} + +#section has the name of the printer +sub add_printer { + my $self = shift; + my ($printer) = @_; + + if (exists $self->{conf}->{$printer}) { + $self->comment_menu($printer, " "); + } + else { + $self->{conf}->{$printer}{printable}{comment} = " "; + $self->{conf}->{$printer}{printer}{comment} = " "; + push @{$self->{tab}}, "[$printer]\n"; + push @{$self->{tab}}, "printer = $printer\n"; + push @{$self->{tab}}, "printable = yes\n"; + $self->{conf}->{$printer}{printer}{value} = $printer; + $self->{conf}->{$printer}{printable}{value} = "yes"; + } +} + +sub list_printers { + my @list if 0; + + return @list if @list; + @list = sort grep /^(?!\#).*/, map { + my ($printer) = split(':', $_); + } cat_("/etc/printcap"); + @list +} + + +sub check_users { + return 'ask_printers' if $o->{var}{wiz_do_printer_sharing} +} + +sub comment_menu { + my $self = shift; + my ($menu, $str) = @_; + + return if (!$menu or !exists $self->{conf}->{$menu}); + $self->{conf}->{$menu}{__comment} = $str; + foreach (keys %{$self->{conf}->{$menu}}) { + ($_ eq "__comment") and next; + $self->{conf}->{$menu}{$_}{comment} = $str; + } +} + +sub comment_var { + my $self = shift; + my ($menu, $var, $str) = @_; + + $self->{conf}->{$menu}{$var}{comment} = $str; +} + +sub chg_var { + my $self = shift; + my ($menu, $var, $str) = @_; + + $self->{conf}->{$menu}{$var}{value} = $str; +} + +# all or selected printers +sub printer_sharing { + my $self = shift; + + if ($o->{var}{wiz_all_printers}) { + $self->comment_menu("printers", " "); + foreach my $printer (keys (%::bool)) { + $self->comment_menu($printer, ";"); + } + } + else { + $self->comment_menu("printers", ";"); + foreach my $printer (keys (%::bool)) { + if (int($::bool{$printer})) { + $self->comment_menu($printer, " "); + $self->add_printer($printer); + } + else { + $self->comment_menu($printer, ";"); + } + } + } +} + +sub get_printers { + if ($o->{var}{wiz_do_printer_sharing}) { + my $string; + $o->{var}{wiz_all_printers} and return "all printers"; + for (my $i; $i < @{$o->{var}{wiz_box_list}}; $i++) { + $string .= "$o->{var}{list_printers}[$i]\n" if $o->{var}{wiz_box_list}[$i] + } + "$string"; + } + else { + "disabled"; + } +} + +sub check_workgroup { + $o->{var}{wiz_workgroup} or return 'error_in_workgroup' +} + +sub ask_acces { + 10; +} + +sub get_write { + $old->{conf}->{public}{"write list"}{value}; +} + +sub get_read { + $old->{conf}->{public}{"read list"}{value}; +} + +sub check_banner { + $o->{var}{wiz_banner} or return 'error_in_banner' +} + +sub get_workgroup { + $old->{conf}->{global}{workgroup}{value} +} + +sub get_banner { + $old->{conf}->{global}{"server string"}{value}; +} + +sub ask_dir { + return 'ask_dir' if $o->{var}{wiz_do_file_sharing}; + return 'ask_printers' if $o->{var}{wiz_do_printer_sharing}; +} + +sub get_dir { + $old->{conf}->{public}{path}{value}; +} + +sub get_file_sharing { + return 0 if ($old->{conf}->{public}{__comment} =~ /\;|\#/); + 1; +} + +sub get_home_sharing { + return 0 if ($old->{conf}->{homes}{__comment} =~ /\;|\#/); + 1; +} + +sub get_netmask { + "192.168.100.1/255.255.255.0"; +} + +sub get_allow_host { + $old->{conf}->{global}{"hosts allow"}{value}; +} + +sub get_deny_host { + $old->{conf}->{global}{"hosts deny"}{value}; +} + +# remember one variable cannot be commented and not in the same file. +sub do_it { + $::testing and return; + my $file = "__WIZ_HOME__/samba_wizard/scripts/smb.conf.default"; + + my $conf = read_conf($file); + $conf->chg_var("global", "workgroup", $o->{var}{wiz_workgroup}); + $conf->chg_var("global", "server string", $o->{var}{wiz_banner}); + $conf->chg_var("public", "write list", $o->{var}{wiz_write_list}) if $o->{var}{wiz_do_file_sharing}; + $conf->chg_var("public", "read list", $o->{var}{wiz_read_list}) if $o->{var}{wiz_do_file_sharing}; + my $ip = $o->itf_get("IPADDR"); + if ($o->{var}{wiz_do_file_sharing}) { + standalone->explanations("Enabling $o->{var}{wiz_dir} samba file sharing"); + $conf->comment_menu("public", " "); + $conf->chg_var("public", "path", $o->{var}{wiz_dir}); + } + else { + standalone->explanations("Disabling samba file sharing"); + $conf->comment_menu("public", ";"); + } + if ($o->{var}{wiz_do_homes}) { + standalone->explanations("Enabling samba homes sharing"); + $conf->comment_menu("homes", " "); + } + else { + standalone->explanations("Disabling samba homes sharing"); + $conf->comment_menu("homes", ";"); + } + standalone->explanations("Samba deny $o->{var}{wiz_hosts_deny}"); + standalone->explanations("Samba allow $o->{var}{wiz_hosts_allow}"); +# $conf->chg_var("global", "hosts deny", $o->{var}{wiz_hosts_deny}); +# $conf->chg_var("global", "hosts allow", $o->{var}{wiz_hosts_allow}); + + if ($o->{var}{wiz_do_printer_sharing}) { + standalone->explanations("Enabling printer sharing"); + $conf->printer_sharing(); + } + else { + standalone->explanations("Disabling printer sharing"); + foreach my $printer (keys (%::bool)) { + if (!int($::bool{$printer})) { + $conf->comment_menu("$printer", ";"); + } + } + $conf->comment_menu("printers", ";"); + } + $conf->write_conf("/etc/samba/smb.conf"); + if (services::is_service_running('smb')) { + services::restart('smb') + } else { + services::start('smb') + } +} 1; |