#!/usr/bin/perl -w # # smbconfig by Guillaume Cottenceau # # Copyright (c) 2000 by Mandrakesoft # # Permission to use, copy, modify, and distribute this software and its # documentation under the terms of the GNU General Public License is hereby # granted. No representations are made about the suitability of this software # for any purpose. It is provided "as is" without express or implied warranty. # See the GNU General Public License for more details. $program_name = "smbconfig"; $version = "0.1.3"; $debug_printings = 0; sub debug_print { $debug_printings && print "[DEBUG] ".$_[0]; } sub debug_print2 { $debug_printings && print $_[0]; } sub fail { die "Exiting on failure.\n"; } sub fail_with_message { print $_[0]; fail(); } @options = ( [ "--debug", "\t\tadditional debug printings", \$debug_printings ] ); @modes = ( [ "--help", "\t\tthis help screen", \&show_options ], [ "--set-security-share", "setup security = share, very useful because we would need otherwise smbpasswd", \&set_security_share ], [ "--set-hosts-allow=<..>", "setup which hosts are allowed to access; for example \"192.168.1. 127.\"", \&set_hosts_allow ], [ "--set-workgroup=", "setup workgroup name", \&set_workgroup ], [ "--set-banner=", "setup the \"server string\" banner of this smb server", \&set_banner ], [ "--remove-homes", "\tremove the default [homes] share (which needs the security=user)", \&remove_homes ], [ "--enable-public", "\tenable read-write share \"public\" at /home/local/samba-public", \&enable_corpo_public ], [ "--enable-printer-access", "setup access to printers of this machine", \&set_printer_access ] ); sub read_conf { open(FH, "+< /etc/samba/smb.conf") or fail_with_message("Could not open /etc/samba/smb.conf\n"); @conf = or fail_with_message("Could not read /etc/samba/smb.conf\n"); debug_print("/etc/samba/smb.conf read, #lines=".$#conf."\n"); } sub write_conf { debug_print("Will write /etc/samba/smb.conf, #lines=".$#conf."\n"); seek(FH, 0, 0) or fail_with_message("Could not seek in /etc/samba/smb.conf\n"); print FH @conf or fail_with_message("Could not write /etc/samba/smb.conf\n"); truncate(FH, tell(FH)) or fail_with_message("Could not truncate /etc/samba/smb.conf\n"); close(FH) or fail_with_message("Could not close /etc/samba/smb.conf\n"); } # set_parameter: section param value sub set_parameter { my $section = $_[0]; my $param = $_[1]; my $value = $_[2]; debug_print("Attempt to find section \"$section\", parameter \"$param\", and setup to \"$value\"\n"); my $i = 0; ($i++ && (lc($_) =~ /^\s*\[$section\]/) && last) foreach (@conf); while (1) { ($i < $#conf) or ($conf[$i] = "$conf[$i]\n\n\t$param = $value") and last; ($conf[$i] =~ /^\s*\[\S+\]/) && ($conf[$i] = "\t$param = $value\n\n$conf[$i]") && last; ($conf[$i] =~ /^\s*$param\s*=/) && ($conf[$i] = "\t$param = $value\n") && last; $i++; } } sub enable_corpo_public { system("mkdir -p /home/local/samba-public") && fail_with_message("Could not create public dir. Probably run as non-root..\n"); system("chown nobody /home/local/samba-public") && fail_with_message("Could not chown public dir to nobody. Requests admin help.\n"); my $i = 0; ($i++ && (lc($_) =~ /^\s*\[public\]/) && fail_with_message("An active [public] section has been found in /etc/samba/smb.conf at line $i\n")) foreach (@conf); push(@conf, ( "$banner"."[public]\n\tcomment = Public space with read-write access\n\tpath = /home/local/samba-public\n\tguest ok = yes\n\twriteable = yes\n" )); $did_something = 1; } sub set_workgroup { set_parameter("global", "workgroup", $_[0]); $did_something = 1; } sub set_banner { set_parameter("global", "server string", $_[0]); $did_something = 1; } sub set_security_share { set_parameter("global", "security", "share"); $did_something = 1; } sub set_hosts_allow { set_parameter("global", "hosts allow", $_[0]); $did_something = 1; } sub set_printer_access { my $i = 0; my $found = 0; # look for default section "printers" ($i++ && (lc($_) =~ /^\s*\[printers\]/) && ($found = 1) && last) foreach (@conf); ($found) && debug_print("Printer section found at line $i\n"); if ($found == 1) { $conf[$i-1] = ";".$conf[$i-1]; while ($i <= $#conf) { (($conf[$i] =~ /^\s*\[\S+\]/) && last) || ($conf[$i] = ";".$conf[$i]); $i++; } debug_print("End of printer section at line $i\n"); } push(@conf, ( "$banner"."[printers]\n\tcomment = All Printers\n\tpath = /var/spool/samba\n\tbrowseable = no\n\tguest ok = yes\n\twritable = no\n\tprintable = yes\n" )); $did_something = 1; } sub remove_homes { my $i = 0; my $found = 0; # look for default section "printers" ($i++ && (lc($_) =~ /^\s*\[homes\]/) && ($found = 1) && last) foreach (@conf); ($found) && debug_print("[homes] section found at line $i\n"); if ($found == 1) { $conf[$i-1] = ";".$conf[$i-1]; while ($i <= $#conf) { (($conf[$i] =~ /^\s*\[\S+\]/) && last) || ($conf[$i] = ";".$conf[$i]); $i++; } debug_print("End of [homes] section at line $i\n"); } $did_something = 1; } sub show_options { print "$program_name v$version helps auto-config of Samba.\n\n"; print "mode:\n"; print "\t".$_->[0]."\t\t".$_->[1]."\n" foreach (@modes); print "options:\n"; print "\t".$_->[0]."\t\t".$_->[1]."\n" foreach (@options); print "\n"; $did_something = 1; } sub arg_without_value { $_[0] =~ /([^=]*)/; return $1; } sub arg_value { $_[0] =~ /([^=]*)=(.*)/; return $2; } # Disable file buffering [to display strings on the tty even when no trailing \n is added] $| = 1; $date = `date`; chop $date; $host = `hostname`; chop $host; $banner = "\n### Autogenerated by $program_name at $date on host $host\n"; $did_something = 0; foreach $arg (@ARGV) { (($arg eq $_->[0]) && (${$_->[2]} = 1)) foreach (@options) } read_conf(); foreach $arg (@ARGV) { ((arg_without_value($arg) eq arg_without_value($_->[0])) && &{$_->[2]}(arg_value($arg))) foreach (@modes) } ($did_something && write_conf()) || show_options(); # Changelog # # 0.1.3 # remove smb.conf end of file bug # # 0.1.2 # added parameter support: hosts allow # # 0.1.1 # added parameter support: server string # support multiple parameter sets at same time # added parameter support: security = share # added remove homes # # 0.1.0 # first version with configure for printers, public, workgroup