diff options
author | carlosg <carlosg> | 2006-10-05 12:27:21 +0000 |
---|---|---|
committer | carlosg <carlosg> | 2006-10-05 12:27:21 +0000 |
commit | f47a9349484ace8adec505c846b54da36b7321d8 (patch) | |
tree | 10da5bfaa0d1367f18b18d1f7c4b87c6cf4655ed | |
parent | 416f7fa1c0224f5ff2cada729b6238d23d6f00ec (diff) |
2006-10-05 Carlos Garnacho <carlosg@gnome.org>
Ported to 1.9.x a huge and incredible patch by Darren Kenny
<Darren.Kenny@Sun.COM> and Erast Benson <erast@gnusolaris.com>
to make s-t-b recognize and configure SunOS based systems.
* Utils/Platform.pm: recognize OpenSolaris and Nexenta properly.
* Utils/File.pm (read_joined_lines): added.
* Users/Shells.pm, Users.pm, Groups.pm: add SunOS case paths.
* Time/NTP.pm, TimeDate.pm: ditto.
* Shares/NFS.pm: parse/modify dfstab in the SunOS case
* Network/Hosts.pm, Ifaces.pm: add code to deal with SunOS network
configuration.
* Init/Services.pm: deal with SMF init system.
-rw-r--r-- | ChangeLog | 15 | ||||
-rw-r--r-- | Init/Services.pm | 167 | ||||
-rw-r--r-- | Network/Hosts.pm | 72 | ||||
-rw-r--r-- | Network/Ifaces.pm | 422 | ||||
-rw-r--r-- | Shares/NFS.pm | 216 | ||||
-rw-r--r-- | Time/NTP.pm | 6 | ||||
-rw-r--r-- | Time/TimeDate.pm | 40 | ||||
-rw-r--r-- | Users/Groups.pm | 82 | ||||
-rw-r--r-- | Users/Shells.pm | 48 | ||||
-rw-r--r-- | Users/Users.pm | 86 | ||||
-rw-r--r-- | UsersConfig.pm | 1 | ||||
-rw-r--r-- | Utils/File.pm | 13 | ||||
-rw-r--r-- | Utils/Platform.pm | 31 |
13 files changed, 1092 insertions, 107 deletions
@@ -1,3 +1,18 @@ +2006-10-05 Carlos Garnacho <carlosg@gnome.org> + + Ported to 1.9.x a huge and incredible patch by Darren Kenny + <Darren.Kenny@Sun.COM> and Erast Benson <erast@gnusolaris.com> + to make s-t-b recognize and configure SunOS based systems. + + * Utils/Platform.pm: recognize OpenSolaris and Nexenta properly. + * Utils/File.pm (read_joined_lines): added. + * Users/Shells.pm, Users.pm, Groups.pm: add SunOS case paths. + * Time/NTP.pm, TimeDate.pm: ditto. + * Shares/NFS.pm: parse/modify dfstab in the SunOS case + * Network/Hosts.pm, Ifaces.pm: add code to deal with SunOS network + configuration. + * Init/Services.pm: deal with SMF init system. + 2006-10-02 Carlos Garnacho <carlosg@gnome.org> * Utils/Parse.pm (escape): fix slight problem when $value has spaces. diff --git a/Init/Services.pm b/Init/Services.pm index 043d417..1a44d77 100644 --- a/Init/Services.pm +++ b/Init/Services.pm @@ -51,6 +51,7 @@ sub get_runlevels "slackware-9.1.0" => "slackware-9.1.0", "gentoo" => "gentoo", "freebsd-5" => "slackware-9.1.0", + "solaris-2.11" => "freebsd-5", ); %runlevels= @@ -80,7 +81,7 @@ sub get_default_runlevel { my $type = &get_init_type (); - return "default" if ($type eq "gentoo" || $type eq "rcng" || $type eq "bsd"); + return "default" if ($type eq "gentoo" || $type eq "rcng" || $type eq "bsd" || $type eq "smf"); return &get_sysv_default_runlevel (); } @@ -103,6 +104,7 @@ sub get_sysv_paths "pld-1.0" => ["$gst_prefix/etc/rc.d", "$gst_prefix/etc/rc.d/init.d", "../init.d"], "vine-3.0" => ["$gst_prefix/etc/rc.d", "$gst_prefix/etc/rc.d/init.d", "../init.d"], "ark" => ["$gst_prefix/etc/rc.d", "$gst_prefix/etc/rc.d/init.d", "../init.d"], + "solaris-2.11" => ["$gst_prefix/etc", "$gst_prefix/etc/init.d", "../init.d"], ); my $res; @@ -524,7 +526,7 @@ sub get_bsd_scripts_list } } - Utils::File::close_file ($fd); + &Utils::File::close_file ($fd); } return \@scripts; @@ -883,7 +885,7 @@ sub get_rcng_status_by_service } } - Utils::File::close_file ($fd); + &Utils::File::close_file ($fd); return $active; } } @@ -1126,6 +1128,158 @@ sub set_suse_services } } +# functions to get/set services info in smf +sub smf_service_exists +{ + my($service) = @_; + my($services) = &get_smf_services_list (); + + foreach $i (@$services) + { + return 1 if ($i =~ /$service/); + } + + return 0; +} + +sub run_smf_svcadm +{ + my ($service, $arg) = @_; + my ($option); + + my %op = + ("stop" => "disable", + "start" => "enable" + ); + + if (&smf_service_exists ($service)) + { + if (!&Utils::File::run ("svcadm $op{$arg} $service")) + { + &Utils::Report::do_report ("service_sysv_op_success", $service, $arg); + &Utils::Report::leave (); + return 0; + } + } + + &Utils::Report::do_report ("service_sysv_op_failed", $service, $arg); + &Utils::Report::leave (); + return -1; +} + +sub get_smf_runlevel_status_by_service +{ + my ($service, $status) = @_; + my (@arr); + + if ($status) + { + push @arr, [ "default", $SERVICE_START, 0 ]; + } + else + { + push @arr, [ "default", $SERVICE_STOP, 0 ]; + } + + return \@arr; +} + +sub get_smf_service_info +{ + my ($service) = @_; + my ($fd, @runlevels); + my $status = 0; + + $fd = &Utils::File::run_pipe_read ("svcs -l $service"); + + while (<$fd>) + { + $status = 1 if (/^state.*online/); + } + + &Utils::File::close_file ($fd); + + $runlevels = &get_smf_runlevel_status_by_service ($service, $status); + $service =~ m/.*\/(.*)$/; + + return ($service, $runlevels); +} + +sub get_smf_services_list +{ + my ($fd, @list); + + $fd = &Utils::File::run_pipe_read ("svcs -H -a"); + + while (<$fd>) + { + next if (/svc:\/milestone/); + + if (/^.*\s*.*\s*svc:\/(.*):.*/) + { + push @list, $1; + } + } + + &Utils::File::close_file ($fd); + return \@list; +} + +sub get_smf_services +{ + my ($service, @arr); + my ($service_list) = &get_smf_services_list (); + + foreach $service (@$service_list) + { + my (@info); + + @info = &get_smf_service_info ($service); + push @arr, \@info if scalar (@info); + } + + return \@arr; +} + +sub set_smf_service_status +{ + my ($service, $rl, $active) = @_; + my ($info); + + $info = &get_smf_service_info ($service); + + #return if service has not changed + return if ($active == @{@$info[0]}[1]); + + if ($active == $SERVICE_START) + { + &Utils::File::run ("svcadm enable -s $service"); + } + else + { + &Utils::File::run ("svcadm disable -s $service"); + } +} + +sub set_smf_services +{ + my ($services) = @_; + my ($action, $rl, $script, $arr); + + foreach $service (@$services) + { + $script = $$service[0]; + $arr = $$service[1]; + + foreach $i (@$arr) + { + $action = $$i[1]; + $rl = $$i[0]; + &set_smf_service_status ($script, $rl, $action); + } + } +} + # generic functions to get the available services sub get_init_type { @@ -1153,6 +1307,10 @@ sub get_init_type { return "suse"; } + elsif ($gst_dist =~ /solaris/) + { + return "smf"; + } else { return "sysv"; @@ -1171,6 +1329,7 @@ sub run_script "gentoo" => \&run_gentoo_script, "rcng" => \&run_rcng_script, "suse" => \&run_sysv_initd_script, + "smf" => \&run_smf_svcadm, ); $type = &get_init_type (); @@ -1188,6 +1347,7 @@ sub get return &get_gentoo_services () if ($type eq "gentoo"); return &get_rcng_services () if ($type eq "rcng"); return &get_suse_services () if ($type eq "suse"); + return &get_smf_services () if ($type eq "smf"); return undef; } @@ -1204,6 +1364,7 @@ sub set &set_gentoo_services ($services) if ($type eq "gentoo"); &set_rcng_services ($services) if ($type eq "rcng"); &set_suse_services ($services) if ($type eq "suse"); + &set_smf_services ($services) if ($type eq "smf"); } 1; diff --git a/Network/Hosts.pm b/Network/Hosts.pm index 54d02ac..25fae76 100644 --- a/Network/Hosts.pm +++ b/Network/Hosts.pm @@ -53,6 +53,7 @@ sub get_fqdn_dist "slackware-9.1.0" => "suse-9.0", "gentoo" => "gentoo", "freebsd-5" => "freebsd-5", + "solaris-2.11" => "solaris-2.11", ); return $dist_map{$Utils::Backend::tool{"platform"}}; @@ -151,6 +152,20 @@ sub get_fqdn_parse_table [ "domain", \&Utils::Parse::split_first_str, RESOLV_CONF, "domain", "[ \t]+" ], ] }, + + "solaris-2.11" => + { + fn => + { + NODENAME => "/etc/nodename", + RESOLV_CONF => "/etc/resolv.conf", + }, + table => + [ + [ "hostname", \&Utils::Parse::get_first_line, NODENAME ], + [ "domain", \&Utils::Parse::split_first_str, RESOLV_CONF, "domain", "[ \t]+" ], + ] + }, ); my $dist = &get_fqdn_dist (); @@ -260,6 +275,20 @@ sub get_fqdn_replace_table [ "domain", \&Utils::Replace::join_first_str, RESOLV_CONF, "domain", "[ \t]+" ], ] }, + + "solaris-2.11" => + { + fn => + { + NODENAME => "/etc/nodename", + RESOLV_CONF => "/etc/resolv.conf", + }, + table => + [ + [ "hostname", \&Utils::Replace::set_first_line, NODENAME ], + [ "domain", \&Utils::Replace::join_first_str, RESOLV_CONF, "domain", "[ \t]+" ], + ] + }, ); my $dist = &get_fqdn_dist (); @@ -326,20 +355,36 @@ sub get_fqdn return ($$hash {"hostname"}, $$hash{"domain"}); } -sub get_hosts +sub parse_hosts_files { - my ($statichosts, @arr); + my ($file) = @_; + my (@arr, %hash, $statichosts, $i); - $statichosts = &Utils::Parse::split_hash ("/etc/hosts", "[ \t]+", "[ \t]+"); + while (@_) + { + $statichosts = &Utils::Parse::split_hash (@_[0], "[ \t]+", "[ \t]+"); + shift @_; + + foreach $i (keys %$statichosts) + { + $hash{$i} = $$statichosts{$i}; + } + } - foreach $i (sort keys %$statichosts) + foreach $i (sort keys %hash) { - push @arr, [$i, $$statichosts{$i}]; + push @arr, [$i, $hash{$i}]; } return \@arr; } +sub get_hosts +{ + return &parse_hosts_files ("/etc/hosts", "/etc/inet/ipnodes") if ($Utils::Backend::tool{"system"} eq "SunOS"); + return &parse_hosts_files ("/etc/hosts"); +} + sub get_dns { my (@dns); @@ -405,7 +450,22 @@ sub set_hosts $hash{$$i[0]} = $$i[1]; } - &Utils::Replace::join_hash ("/etc/hosts", "[ \t]+", "[ \t]+", \%hash); + if ($Utils::Backend::tool {"system"} eq "SunOS") + { + &Utils::Replace::join_hash ("/etc/inet/ipnodes", "[ \t]+", "[ \t]+", \%hash); + + # save only IPv4 entries in /etc/hosts + foreach $i (keys %hash) + { + delete $hash{$i} if ($i =~ /[a-fA-F:]/); + } + + &Utils::Replace::join_hash ("/etc/hosts", "[ \t]+", "[ \t]+", \%hash); + } + else + { + &Utils::Replace::join_hash ("/etc/hosts", "[ \t]+", "[ \t]+", \%hash); + } } sub set_dns diff --git a/Network/Ifaces.pm b/Network/Ifaces.pm index 51c3b71..2f2022e 100644 --- a/Network/Ifaces.pm +++ b/Network/Ifaces.pm @@ -26,6 +26,7 @@ package Network::Ifaces; use Utils::Util; +use Utils::Parse; use Init::Services; # FIXME: this function isn't IPv6-aware @@ -219,14 +220,15 @@ sub get_interface_type return $types_cache{$dev}; } -sub get_freebsd_interfaces_info +sub get_sunos_freebsd_interfaces_info { + my ($command) = @_; my ($dev, %ifaces, $fd); &Utils::Report::enter (); &Utils::Report::do_report ("network_iface_active_get"); - $fd = &Utils::File::run_pipe_read ("ifconfig"); + $fd = &Utils::File::run_pipe_read ($command); return {} if $fd eq undef; while (<$fd>) @@ -254,6 +256,16 @@ sub get_freebsd_interfaces_info return %ifaces; } +sub get_freebsd_interfaces_info +{ + return &get_sunos_freebsd_interfaces_info ("ifconfig"); +} + +sub get_sunos_interfaces_info +{ + return &get_sunos_freebsd_interfaces_info ("ifconfig -a"); +} + sub get_linux_interfaces_info { my ($dev, %ifaces, $fd); @@ -296,6 +308,7 @@ sub get_interfaces_info return &get_linux_interfaces_info if ($Utils::Backend::tool{"system"} eq "Linux"); return &get_freebsd_interfaces_info if ($Utils::Backend::tool{"system"} eq "FreeBSD"); + return &get_sunos_interfaces_info if ($Utils::Backend::tool{"system"} eq "SunOS"); return undef; } @@ -485,6 +498,27 @@ sub set_freebsd_bootproto return &Utils::Replace::set_sh ($file, "ifconfig_$dev", ""); } +sub get_sunos_bootproto +{ + my ($dhcp_file, $dev) = @_; + return (&Utils::File::exists ($dhcp_file)) ? "dhcp" : "none"; +} + +sub set_sunos_bootproto +{ + my ($dhcp_file, $file, $iface, $value) = @_; + + if ($value eq "dhcp") + { + &Utils::File::save_buffer ("", $file); + &Utils::File::run ("touch $dhcp_file"); + } + else + { + &Utils::File::remove ($dhcp_file); + } +} + # Functions to get the system interfaces, these are distro dependent sub sysconfig_dir_get_existing_ifaces { @@ -998,6 +1032,255 @@ sub set_slackware_auto } } +sub get_sunos_auto +{ + my ($file, $iface) = @_; + return &Utils::File::exists ($file); +} + +sub lookup_host +{ + my ($file) = @_; + my ($arr, $h); + + $arr = &Network::Hosts::get_hosts (); + + foreach $h (@$arr) + { + my ($ip, $aliases) = @$h; + my ($alias); + + foreach $alias (@$aliases) + { + return $ip if ($alias eq $host) + } + } +} + +sub lookup_ip +{ + my ($ip) = @_; + my ($hosts); + + $hosts = &Utils::Parse::split_hash ("/etc/hosts", "[ \t]+", "[ \t]+"); + return @{$$hosts{$ip}}[0] if (exists $$hosts{$ip}); + + if ($Utils::Backend::tool {"system"} eq "SunOS") + { + $hosts = &Utils::Parse::split_hash ("/etc/inet/ipnodes", "[ \t]+", "[ \t]+"); + return @{$$hosts{$ip}}[0] if (exists $$hosts{$ip}); + } +} + +sub get_sunos_hostname_iface_value +{ + my ($file, $re) = @_; + my (@buff, $i); + + $buff = &Utils::File::load_buffer ($file); + &Utils::File::join_buffer_lines ($buff); + $i = 0; + + while ($$buff[$i]) + { + return $1 if ($$buff[$i] =~ "$re"); + $i++; + } +} + +sub get_sunos_address +{ + my ($file, $dev) = @_; + my ($address); + + $address = &get_sunos_hostname_iface_value ($file, "^\s*([0-9.]+)\s*"); + return $address if ($address); + + $address = &get_sunos_hostname_iface_value ($file, "^\s*([0-9a-zA-Z-_]+)\s*"); + return &lookup_host ($address); +} + +sub set_sunos_address +{ + my ($file, $dev, $addr) = @_; + my ($buf, $host); + + if (&Utils::File::exists ($file)) + { + $buf = &Utils::File::read_joined_lines ($file); + $host = &lookup_ip ($addr); + + if ($buf =~ /^(\s*[0-9\.]+)\s+/ || + $buf =~ /^(\s*[0-9a-zA-Z\-_]+)\s/) + { + $buf =~ s/$1/$addr/; + &Utils::File::save_buffer ($buf, $file); + return; + } + } + + # save address from scratch + &Utils::File::save_buffer ($addr, $file); +} + +sub get_sunos_netmask +{ + my ($file, $dev, $use_dhcp) = @_; + my ($buf); + + $buf = &Utils::File::read_joined_lines ($file); + + if ($buf =~ /\s+netmask\s+([0-9.]+)\s*/) + { + return $1; + } + + return "255.0.0.0" if ($use_dhcp ne "dhcp"); +} + +sub set_sunos_netmask +{ + my ($file, $masks_file, $dev, $addr, $mask) = @_; + my ($buff, $i, $network, $found); + + # modify /etc/netmasks + $network = &Utils::Util::ip_calc_network ($addr, $mask); + $buff = &Utils::File::load_buffer ($masks_file); + $found = 0; + $i = 0; + + while ($$buff[$i]) + { + if ($$buff[$i] =~ /\s*$network\s+.+/) + { + $$buff[$i] = "$network\t$mask"; + $found = 1; + } + + $i++; + } + + push @$buff, "$network\t$mask" if (!$found); + &Utils::File::save_buffer ($buff, $masks_file); + + # modify hostname.$dev + $buff = &Utils::File::read_joined_lines ($file); + + if ($buff =~ /\s*(netmask [0-9\.]+)/) + { + $buff =~ s/$1/netmask $mask/; + } + else + { + $buff .= " netmask $mask"; + } + + &Utils::File::save_buffer ($buff, $file); +} + +sub get_sunos_gateway +{ + my ($file, $dev) = @_; + my ($line); + + my $line = &Utils::Parse::get_first_line ($file); + + if ($line =~ /^\s*([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)\s*/) + { + return $1; + } + elsif ($buf =~ /^\s*([0-9a-zA-Z-_]+)\s*/) + { + return &lookup_host ($1); + } +} + +sub set_sunos_gateway +{ + my ($file, $dev, $gateway) = @_; + &Utils::File::save_buffer ("$gateway\n", $file); +} + +sub get_sunos_wireless +{ + my ($dev, $opt) = @_; + my ($fd, $essid, $key_type); + + $fd = &Utils::File::run_pipe_read ("wificonfig -i $dev"); + return if (!$fd); + + while (<$fd>) + { + if (/$opt:\s+(.*)/) + { + return $1; + } + } + + &Utils::File::close_file ($fd); + return; +} + +sub set_sunos_wireless +{ + my ($dev, $opt, $essid, $value) = @_; + my ($profile); + + my $profile = &get_sunos_profile_from_essid ($essid); + + if ($opt eq "essid") + { + &Utils::File::run ("wificonfig setprofileparam $profile essid='$value'"); + } + elsif ($opt eq "key_type") + { + $value = "wep" if ($value ne "none"); + &Utils::File::run ("wificonfig setprofileparam $profile encryption=$value"); + } + elsif ($opt eq "key") + { + &Utils::File::run ("wificonfig setprofileparam $profile wepkey1=$value"); + &Utils::File::run ("wificonfig setprofileparam $profile wepkeyindex=1"); + } +} + +sub get_sunos_real_wep_key +{ + my ($secret, $profile, $index) = @_; + + $index--; + $index = 0 if ($index < 0); + + my @wificonfig_profiles = &Utils::Parse::get_ini_sections ($secret); + return undef unless (grep (/^$profile$/, @wificonfig_profiles)); + + return &Utils::Parse::get_ini ($secret, $profile, "wepkey$index"); +} + +sub get_sunos_profile_from_essid +{ + my ($essid) = @_; + my ($profilename); + + $profilename = $essid; + $profilename =~ s/\W/_/g; + + $profilename = "gst-default" unless ( $profilename ); + return $profilename +} + +sub get_sunos_wireless_key +{ + my ($secret, $dev) = @_; + my ($essid, $index, $profile); + + $essid = &get_sunos_wireless ($dev, "essid"); + $index = &get_sunos_wireless ($dev, "wepkeyindex"); + $profile = &get_sunos_profile_from_essid ($essid); + + return &get_sunos_real_wep_key ($secret, $profile, $index); +} + sub get_freebsd_auto { my ($file, $defaults_file, $iface) = @_; @@ -1268,6 +1551,27 @@ sub activate_freebsd_interface } } +sub activate_sunos_interface +{ + my ($hash, $old_hash, $enabled, $force) =@_; + my ($dev) = $$hash{"dev"}; + + if ($force || &interface_changed ($hash, $old_hash)) + { + if ($enabled) + { + &Utils::File::run ("svcadm restart svc:/network/physical"); # Restart physical network interfaces + &Utils::File::run ("svcadm restart svc:/network/service"); # Restart name services + } + else + { + #&Utils::File::run ("ifconfig $dev unplumb"); + &Utils::File::run ("svcadm restart svc:/network/physical"); # Restart physical network interfaces + &Utils::File::run ("svcadm restart svc:/network/service"); # Restart name services + } + } +} + sub remove_pap_entry { my ($file, $login) = @_; @@ -1467,6 +1771,16 @@ sub delete_freebsd_interface &Utils::File::remove ($startif); } +sub delete_sunos_interface +{ + my ($old_hash) = @_; + my ($dev); + + $dev = $$old_hash{"dev"}; + &Utils::File::remove ("/etc/hostname.$dev"); + &Utils::File::remove ("/etc/dhcp.$dev"); +} + # FIXME: should move to external file!!! sub create_pppscript { @@ -1680,6 +1994,7 @@ sub get_interface_dist "slackware-9.1.0" => "slackware-9.1.0", "gentoo" => "gentoo", "freebsd-5" => "freebsd-5", + "solaris-2.11" => "solaris-2.11", ); return $dist_map{$Utils::Backend::tool{"platform"}}; @@ -2341,6 +2656,56 @@ sub get_interface_parse_table [ "persist", \&get_freebsd_ppp_persist, [ STARTIF, IFACE ]], ] }, + + "solaris-2.11" => + { + fn => + { + INTERFACE => "/etc/hostname.#iface#", + DHCP_FILE => "/etc/dhcp.#iface#", + SECRET => "/etc/inet/secret/wifiwepkey", + DEFAULTROUTER => "/etc/defaultrouter", + IFACE => "#iface#", + TYPE => "#type#", + CHAT => "/etc/chatscripts/%section%", + PPP_OPTIONS => "/etc/ppp/peers/%section%", + PAP => "/etc/ppp/pap-secrets", + CHAP => "/etc/ppp/chap-secrets", + }, + table => + [ + [ "dev", \&Utils::Parse::get_trivial, IFACE ], + [ "bootproto", \&get_sunos_bootproto, [ DHCP_FILE, IFACE ]], + [ "auto", \&get_sunos_auto, [INTERFACE, IFACE]], + [ "address", \&get_sunos_address, [INTERFACE, IFACE]], + [ "netmask", \&get_sunos_netmask, [INTERFACE, IFACE], "%bootproto%" ], + [ "gateway", \&get_sunos_gateway, DEFAULTROUTER, IFACE ], + # FIXME: no broadcast nor network + [ "essid", \&get_sunos_wireless, [IFACE, "essid" ]], + [ "key_type", \&get_sunos_wireless, [IFACE, "encryption" ]], + [ "key", \&get_sunos_wireless_key, [SECRET, IFACE ]], + [ "update_dns", \&check_type, [TYPE, "(modem|isdn)", \&Utils::Parse::get_kw, PPP_OPTIONS, "usepeerdns" ]], + [ "noauth", \&check_type, [TYPE, "(modem|isdn)", \&Utils::Parse::get_kw, PPP_OPTIONS, "noauth" ]], + [ "mtu", \&check_type, [TYPE, "(modem|isdn)", \&Utils::Parse::split_first_str, PPP_OPTIONS, "mtu", "[ \t]+" ]], + [ "mru", \&check_type, [TYPE, "(modem|isdn)", \&Utils::Parse::split_first_str, PPP_OPTIONS, "mru", "[ \t]+" ]], + [ "serial_port", \&check_type, [TYPE, "modem", \&Utils::Parse::get_ppp_options_re, PPP_OPTIONS, "^(/dev/[^ \t]+)" ]], + [ "serial_speed", \&check_type, [TYPE, "modem", \&Utils::Parse::get_ppp_options_re, PPP_OPTIONS, "^([0-9]+)" ]], + [ "login", \&check_type, [TYPE, "(modem|isdn)", \&Utils::Parse::get_ppp_options_re, PPP_OPTIONS, "^user \"?([^\"]*)\"?" ]], + [ "password", \&check_type, [TYPE, "(modem|isdn)", \&get_pap_passwd, PAP, "%login%" ]], + [ "password", \&check_type, [TYPE, "(modem|isdn)", \&get_pap_passwd, CHAP, "%login%" ]], + [ "set_default_gw", \&check_type, [TYPE, "(modem|isdn)", \&Utils::Parse::get_kw, PPP_OPTIONS, "defaultroute" ]], + [ "debug", \&check_type, [TYPE, "(modem|isdn)", \&Utils::Parse::get_kw, PPP_OPTIONS, "debug" ]], + [ "persist", \&check_type, [TYPE, "(modem|isdn)", \&Utils::Parse::get_kw, PPP_OPTIONS, "persist" ]], + [ "serial_escapechars", \&check_type, [TYPE, "modem", \&Utils::Parse::split_first_str, PPP_OPTIONS, "escape", "[ \t]+" ]], + [ "serial_hwctl", \&check_type, [TYPE, "modem", \&Utils::Parse::get_kw, PPP_OPTIONS, "crtscts" ]], + [ "external_line", \&check_type, [TYPE, "modem", \&Utils::Parse::get_from_chatfile, CHAT, "atd[^0-9]([0-9*#]*)[wW]" ]], + [ "external_line", \&check_type, [TYPE, "isdn", \&Utils::Parse::get_ppp_options_re, PPP_OPTIONS, "^number[ \t]+(.+)[wW]" ]], + [ "phone_number", \&check_type, [TYPE, "isdn", \&Utils::Parse::get_ppp_options_re, PPP_OPTIONS, "^number.*[wW \t](.*)" ]], + [ "phone_number", \&check_type, [TYPE, "modem", \&Utils::Parse::get_from_chatfile, CHAT, "atd.*[ptwW]([0-9, -]+)" ]], + [ "dial_command", \&check_type, [TYPE, "modem", \&Utils::Parse::get_from_chatfile, CHAT, "(atd[tp])[0-9, -w]+" ]], + [ "volume", \&check_type, [TYPE, "modem", \&get_modem_volume, CHAT ]], + ] + }, ); my $dist = &get_interface_dist (); @@ -2995,7 +3360,58 @@ sub get_interface_replace_table [ "dial_command", \&set_pppconf_dial_command, [ PPPCONF, STARTIF, IFACE ]], [ "volume", \&set_pppconf_volume, [ PPPCONF, STARTIF, IFACE ]], ] - } + }, + + "solaris-2.11" => + { + iface_set => \&activate_sunos_interface, + iface_delete => \&delete_sunos_interface, + fn => + { + INTERFACE => "/etc/hostname.#iface#", + DHCP_FILE => "/etc/dhcp.#iface#", + MASKS_FILE => "/etc/netmasks", + IFACE => "#iface#", + TYPE => "#type#", + DEFAULTROUTER => "/etc/defaultrouter", + CHAT => "/etc/chatscripts/%section%", + PPP_OPTIONS => "/etc/ppp/peers/%section%", + PAP => "/etc/ppp/pap-secrets", + CHAP => "/etc/ppp/chap-secrets", + }, + table => + [ + [ "address", \&set_sunos_address, [ INTERFACE, IFACE ]], + [ "netmask", \&set_sunos_netmask, [ INTERFACE, MASKS_FILE, IFACE ], "%address%" ], + [ "gateway", \&set_sunos_gateway, [DEFAULTROUTER, IFACE]], + [ "bootproto", \&set_sunos_bootproto, [ DHCP_FILE, INTERFACE, IFACE ]], + #FIXME: there seems to be no way of setting an interface as noauto without removing the config file + #[ "auto", \&set_sunos_auto, [IFACE]], + [ "essid", \&set_sunos_wireless, [IFACE], "essid" ], + [ "key", \&set_sunos_wireless, [IFACE], "key" ], + [ "key_type", \&set_sunos_wireless, [IFACE], "key_type" ], + # Modem stuff + [ "section", \&check_type, [TYPE, "modem", \&Utils::Replace::set_ppp_options_connect, PPP_OPTIONS ]], + [ "phone_number", \&check_type, [TYPE, "modem", \&create_pppscript, CHAT ]], + [ "phone_number", \&check_type, [TYPE, "isdn", \&create_isdn_options, PPP_OPTIONS ]], + [ "update_dns", \&check_type, [TYPE, "(modem|isdn)", \&Utils::Replace::set_kw, PPP_OPTIONS, "usepeerdns" ]], + [ "noauth", \&check_type, [TYPE, "(modem|isdn)", \&Utils::Replace::set_kw, PPP_OPTIONS, "noauth" ]], + [ "set_default_gw", \&check_type, [TYPE, "(modem|isdn)", \&Utils::Replace::set_kw, PPP_OPTIONS, "defaultroute" ]], + [ "debug", \&check_type, [TYPE, "(modem|isdn)", \&Utils::Replace::set_kw, PPP_OPTIONS, "debug" ]], + [ "persist", \&check_type, [TYPE, "(modem|isdn)", \&Utils::Replace::set_kw, PPP_OPTIONS, "persist" ]], + [ "serial_port", \&check_type, [TYPE, "modem", \&Utils::Replace::set_ppp_options_re, PPP_OPTIONS, "^(/dev/[^ \t]+)" ]], + [ "serial_speed", \&check_type, [TYPE, "modem", \&Utils::Replace::set_ppp_options_re, PPP_OPTIONS, "^([0-9]+)" ]], + [ "login", \&check_type, [TYPE, "(modem|isdn)", \&Utils::Replace::set_ppp_options_re, PPP_OPTIONS, "^user (.*)", "user \"%login%\"" ]], + [ "password", \&check_type, [TYPE, "(modem|isdn)", \&set_pap_passwd, PAP, "%login%" ]], + [ "password", \&check_type, [TYPE, "(modem|isdn)", \&set_pap_passwd, CHAP, "%login%" ]], + [ "dial_command", \&check_type, [TYPE, "modem", \&Utils::Replace::set_chat, CHAT, "(atd[tp])[0-9w, -]+" ]], + [ "phone_number", \&check_type, [TYPE, "modem", \&Utils::Replace::set_chat, CHAT, "atd[tp]([0-9w]+)" ]], + [ "external_line", \&check_type, [TYPE, "modem", \&Utils::Replace::set_chat, CHAT, "atd[tp]([0-9w, -]+)", "%external_line%W%phone_number%" ]], + [ "phone_number", \&check_type, [TYPE, "isdn", \&Utils::Replace::set_ppp_options_re, PPP_OPTIONS, "^number (.*)", "number %phone_number%" ]], + [ "external_line", \&check_type, [TYPE, "isdn", \&Utils::Replace::set_ppp_options_re, PPP_OPTIONS, "^number (.*)", "number %external_line%W%phone_number%" ]], + [ "volume", \&check_type, [TYPE, "modem", \&set_modem_volume, CHAT ]], + ] + }, ); my $dist = &get_interface_dist (); diff --git a/Shares/NFS.pm b/Shares/NFS.pm index 47f1d96..271c810 100644 --- a/Shares/NFS.pm +++ b/Shares/NFS.pm @@ -24,7 +24,7 @@ use Utils::Parse; sub get_distro_nfs_file { - # This is quite generic + return "/etc/dfs/dfstab" if ($Utils::Backend::tool{"system"} eq "SunOS"); return "/etc/exports"; } @@ -67,24 +67,132 @@ sub get_share_info return \@share_info; } +sub get_share_info_sunos +{ + my ($str) = @_; + my (@options, $opt, @values, @share_info); + + @options = split (/\s*,\s*/, $str); + + foreach $opt (@options) + { + my ($option, $value); + + @values = split /\s*=\s*/, $opt; + $option = $values[0]; + $value = $values[1]; + + # only support "rw" and "ro" at the moment + if ($option eq "rw" || $option eq "ro") + { + my ($rw, $client); + $rw = ($option eq "rw") ? 1 : 0; + + if (!$value) + { + push @share_info, [ $rw, "0.0.0.0/0" ]; + } + else + { + my @clients; + + # get the clients list + @clients = split (/:/, $value); + + foreach $client (@clients) + { + push @share_info, [ $client, $rw ]; + } + } + } + } + + return \@share_info; +} + +sub get_client_opts_sunos +{ + my ($clients) = @_; + my (@rw_clients, @ro_clients, $client, $str, $i); + + foreach $i (@$clients) + { + #FIXME: broken logic? + if (!$$i[1]) + { + push @rw_clients, $$i[0]; + } + else + { + push @ro_clients, $$i[0]; + } + } + + # get rw clients + if (scalar (@rw_clients)) + { + $str .= "rw=" . join (":", @rw_clients); + } + + # get ro clients + if (scalar (@ro_clients)) + { + $str .= ",ro=" . join (":", @ro_clients); + } + + return $str; +} + sub get_export_line { my ($share) = @_; - my ($str); - - $str = sprintf ("%-15s ", $$share[0]); + my ($str, $i); - foreach $i (@{$$share[1]}) + if ($Utils::Backend::tool{"system"} eq "SunOS") { - $str .= $$i[0]; - $str .= "(rw)" if (!$$i[1]); - $str .= " "; + $str = "share -F nfs"; + $str .= " -o " . &get_client_opts_sunos ($$share[1]); + $str .= " " . $$share[0]; + } + else + { + $str = sprintf ("%-15s ", $$share[0]); + + foreach $i (@{$$share[1]}) + { + $str .= $$i[0]; + #FIXME: broken logic? + $str .= "(rw)" if (!$$i[1]); + $str .= " "; + } + + $str .= "\n"; } - $str .= "\n"; return $str; } +sub share_line_matches +{ + my ($share, $line) = @_; + + return 0 if (&Utils::Util::ignore_line ($line)); + chomp $line; + + if ($Utils::Backend::tool{"system"} eq "SunOS") + { + return 0 if ($line !~ /\-F\s+nfs/); + return 1 if ($line =~ /$$share[0]$/); + } + else + { + my @arr; + + @arr = split /[ \t]+/, $$buff[$i]; + return 1 if ($arr[0] eq $$share[0]); + } +} + sub add_entry { my ($share, $file) = @_; @@ -102,14 +210,14 @@ sub delete_entry my ($buff, $i, $line, @arr); $buff = &Utils::File::load_buffer ($file); + &Utils::File::join_buffer_lines ($buff); $i = 0; while ($$buff[$i]) { - if (!&Utils::Util::ignore_line ($$buff[$i])) + if (&share_line_matches ($share, $$buff[$i])) { - @arr = split /[ \t]+/, $$buff[$i]; - delete $$buff[$i] if ($arr[0] eq $$share[0]); + delete $$buff[$i]; } $i++; @@ -125,14 +233,14 @@ sub change_entry my ($buff, $i, $line, @arr); $buff = &Utils::File::load_buffer ($file); + &Utils::File::join_buffer_lines ($buff); $i = 0; while ($$buff[$i]) { - if (!&Utils::Util::ignore_line ($$buff[$i])) + if (&share_line_matches ($old_share, $$buff[$i])) { - @arr = split /[ \t]+/, $$buff[$i]; - $$buff[$i] = &get_export_line ($share) if ($arr[0] eq $$old_share[0]); + $$buff[$i] = &get_export_line ($share); } $i++; @@ -142,22 +250,78 @@ sub change_entry &Utils::File::save_buffer ($buff, $file); } +sub get_dfstab_shares +{ + my ($file, $type) = @_; + my ($buff, $line, @arr); + + # dfstab example: + # + # share [-F fstype] [-o fs_options ] [-d description] [pathname [resourcename]] + # .e.g, + # share -F nfs -o rw=engineering -d "home dirs" /export/home2 + + $buff = &Utils::File::load_buffer ($file); + &Utils::File::join_buffer_lines ($buff); + return [] if (!$buff); + + foreach $line (@$buff) + { + chomp $line; + + if ($line =~ /^\s*\S*share\s+(.*)/) + { + my $share; + my $line = $1; + + if ($line =~ /\s-F\s+(\S+)/) { $share->{'type'} = $1; } + else { $share->{'type'} = "nfs"; } + + # skip undesired shares + next if ($share->{'type'} ne $type); + + if ($line =~ /\s+(\/\S+)/ || $line =~ /\s+(\/)/ || $line eq "/") { $share->{'dir'} = $1; } + if ($line =~ /-o\s+"([^\"]+)"/ || $line =~ /-o\s+(\S+)/) { $share->{'opts'} = $1; } + #if ($line =~ /-d\s+\"([^\"]+)\"/ || $line =~ /-d\s+(\S+)/) { $share->{'desc'} = $1; } + + push @arr, $share; + } + } + + return \@arr; +} + sub get { - my ($nfs_exports_name); + my ($nfs_file); my (@sections, @table, $entries); - my $point, $share_info; + my ($point, $share_info); - $nfs_exports_name = &get_distro_nfs_file (); + $nfs_file = &get_distro_nfs_file (); - $entries = &Utils::Parse::split_hash_with_continuation ($nfs_exports_name, "[ \t]+", "[ \t]+"); + if ($Utils::Backend::tool{"system"} eq "SunOS") + { + my $shares = &get_dfstab_shares ($nfs_file, "nfs"); - foreach $point (keys %$entries) + foreach $share (@$shares) + { + $point = $share->{'dir'}; + + $share_info = &get_share_info_sunos ($share->{'opts'}); + push @table, [ $point, $share_info ]; + } + } + else { - my $clients = $$entries{$point}; + $entries = &Utils::Parse::split_hash_with_continuation ($nfs_file, "[ \t]+", "[ \t]+"); + + foreach $point (keys %$entries) + { + my $clients = $$entries{$point}; - $share_info = &get_share_info ($clients); - push @table, [ $point, $share_info ]; + $share_info = &get_share_info ($clients); + push @table, [ $point, $share_info ]; + } } return \@table; @@ -207,6 +371,12 @@ sub set &change_entry ($old_config_hash{$i}, $config_hash{$i}, $nfs_exports_name); } } + + if ($Utils::Backend::tool{"system"} eq "SunOS") + { + &Utils::File::run ("unshareall -F nfs"); + &Utils::File::run ("shareall -F nfs"); + } } 1; diff --git a/Time/NTP.pm b/Time/NTP.pm index 341857d..21acc2b 100644 --- a/Time/NTP.pm +++ b/Time/NTP.pm @@ -41,12 +41,14 @@ sub get_config_file () "pld-1.0" => "pld-1.0", "vine-3.0" => "redhat-6.2", "freebsd-5" => "redhat-6.2", + "solaris-2.11" => "solaris-2.11", ); my %dist_table = ( - "redhat-6.2" => "/etc/ntp.conf", - "pld-1.0" => "/etc/ntp/ntp.conf" + "redhat-6.2" => "/etc/ntp.conf", + "pld-1.0" => "/etc/ntp/ntp.conf", + "solaris-2.11" => "/etc/inet/ntp.conf", ); my $dist = $dist_map{$Utils::Backend::tool{"platform"}}; diff --git a/Time/TimeDate.pm b/Time/TimeDate.pm index 0e57b86..9cee1a8 100644 --- a/Time/TimeDate.pm +++ b/Time/TimeDate.pm @@ -47,7 +47,8 @@ sub change_timedate my $system_table = { "Linux" => "date -u %02d%02d%02d%02d%04d.%02d", - "FreeBSD" => "date -u -f %%m%%d%%H%%M%%Y.%%S %02d%02d%02d%02d%04d.%02d" + "FreeBSD" => "date -u -f %%m%%d%%H%%M%%Y.%%S %02d%02d%02d%02d%04d.%02d", + "SunOS" => "date -u %02d%02d%02d%02d%04d.%02d", }; $command = sprintf ($$system_table {$Utils::Backend::tool{"system"}}, @@ -62,7 +63,7 @@ sub change_timedate sub set_utc_time { my ($time) = @_; - my ($res, $xscreensaver_owners); + my ($res); $res = &change_timedate ($time); @@ -72,7 +73,7 @@ sub set_utc_time sub time_sync_hw_from_sys { - &Utils::File::run ("hwclock --systohc"); + &Utils::File::run ("hwclock --systohc") if ($$tool{"system"} eq "Linux"); return 0; } @@ -116,8 +117,8 @@ sub get_timezone $zone = ""; } - return $zone; close (TZLIST); + return $zone; } sub set_timezone @@ -163,6 +164,7 @@ sub get_dist "pld-1.0" => "redhat-6.2", "vine-3.0" => "redhat-6.2", "freebsd-5" => "redhat-6.2", + "solaris-2.11" => "solaris-2.11", ); return $dist_map{$Utils::Backend::tool{"platform"}}; @@ -214,6 +216,20 @@ sub conf_get_parse_table [ "timezone", \&Utils::Parse::get_sh, RC_LOCAL, TIMEZONE ], ] }, + + "solaris-2.11" => + { + fn => + { + NTP_CONF => "/etc/inet/ntp.conf", + INIT_FILE => "/etc/default/init" + }, + table => + [ + [ "local_time", \&get_utc_time ], + [ "timezone", \&Utils::Parse::get_sh, INIT_FILE, TZ ], + ] + }, ); my $dist = &get_dist(); @@ -272,6 +288,22 @@ sub conf_get_replace_table [ "local_time", \&set_utc_time ], ] }, + + "solaris-2.11" => + { + fn => + { + ZONEINFO => "/usr/share/lib/zoneinfo", + LOCAL_TIME => "/etc/localtime", + INIT_FILE => "/etc/default/init" + }, + table => + [ + [ "timezone", \&Utils::Replace::set_sh, INIT_FILE, TZ ], + [ "timezone", \&set_timezone, [LOCAL_TIME, ZONEINFO] ], + [ "local_time", \&set_utc_time ], + ] + }, ); my $dist = &get_dist (); diff --git a/Users/Groups.pm b/Users/Groups.pm index 118ad66..8b13f00 100644 --- a/Users/Groups.pm +++ b/Users/Groups.pm @@ -41,6 +41,7 @@ $cmd_groupmod = &Utils::File::locate_tool ("groupmod"); $cmd_delgroup = &Utils::File::locate_tool ("delgroup"); $cmd_addgroup = &Utils::File::locate_tool ("addgroup"); +$cmd_usermod = &Utils::File::locate_tool ("usermod"); $cmd_gpasswd = &Utils::File::locate_tool ("gpasswd"); $cmd_pw = &Utils::File::locate_tool ("pw"); @@ -61,6 +62,70 @@ sub del_group &Utils::File::run ($command); } +# This is only for Linux and SunOS, +# pw groupadd manages this in FreeBSD +sub add_user_to_group +{ + my ($group, $user) = @_; + my ($command); + + if ($Utils::Backend::tool{"system"} eq "SunOS") + { + my ($groups, @arr); + + $groups = &Utils::File::run_backtick ("groups $user"); + $groups =~ s/.*://; + chomp ($groups); + + @arr = split (/ /, $groups); + push @arr, $group; + $groups = join (',', @arr); + $groups =~ s/^,//; + $groups =~ s/,$//; + + $command = "$cmd_usermod -G $groups $user"; + } + else + { + $command = "$cmd_gpasswd -a \'" . $user . "\' " . $group; + } + + &Utils::File::run ($command); +} + +# This is only for Linux and SunOS, +# pw groupdel manages this in FreeBSD +sub delete_user_from_group +{ + my ($group, $user) = @_; + my ($command); + + if ($Utils::Backend::tool{"system"} eq "SunOS") + { + my ($groups, @arr); + + $groups = &Utils::File::run_backtick ("groups $user"); + $groups =~ s/.*://; + chomp ($groups); + + # delete the user + $groups =~ s/[ \t]+$group//; + + @arr = split (/ /, $groups); + $groups = join (',', @arr); + $groups =~ s/^,//; + $groups =~ s/,$//; + + $command = "$cmd_usermod -G $groups $user"; + } + else + { + $command = "$cmd_gpasswd -d \'" . $user . "\' \'" . $group . "\'"; + } + + &Utils::File::run ($command); +} + sub add_group { my ($group) = @_; @@ -95,10 +160,7 @@ sub add_group foreach $user (sort @$u) { - $command = "$cmd_gpasswd -a \'" . $user . - "\' " . $$group[$LOGIN]; - - &Utils::File::run ($command); + &add_user_to_group ($$group[$LOGIN], $user); } } } @@ -144,19 +206,13 @@ sub change_group { # users with state 2 are those that only appeared # in the old group configuration, so we must delete them - $command = "$cmd_gpasswd -d \'" . $user . "\' \'" . - $$new_group[$LOGIN] . "\'"; - - &Utils::File::run ($command); + &delete_user_from_group ($$new_group [$LOGIN], $user); } - else + elsif ($state == 1) { # users with state 1 are those who were added # to the new group configuration - $command = "$cmd_gpasswd -a \'" . $user . "\' \'" . - $$new_group[$LOGIN] . "\'"; - - &Utils::File::run ($command); + &add_user_to_group ($$new_group[$LOGIN], $user); } } } diff --git a/Users/Shells.pm b/Users/Shells.pm index 1c473ec..6ebcfa3 100644 --- a/Users/Shells.pm +++ b/Users/Shells.pm @@ -37,27 +37,46 @@ sub get_files return $shells_file; } +sub push_shell +{ + my ($shells, $shell) = @_; + push @$shells, $shell if (stat ($shell)); +} + sub get { - my ($ifh, @shells); + my ($ifh, @shells, $shell); # Init @shells, I think every *nix has /bin/false. - if (stat ("/bin/false")) - { - push @shells, "/bin/false"; - } - - $ifh = &Utils::File::open_read_from_names($shells_file); - return unless $ifh; + &push_shell (\@shells, "/bin/false"); - while (<$ifh>) + if ($Utils::Backend::tool{"system"} eq "SunOS") { - next if &Utils::Util::ignore_line ($_); - chomp; - push @shells, $_ if (stat ($_)); + #SunOS doesn't have anything like /etc/shells + my $possible_shells = + [ "/bin/bash", "/bin/csh", "/bin/jsh", "/bin/ksh", "/bin/pfcsh", "/bin/pfksh", "/bin/pfsh", "/bin/sh", + "/bin/tcsh", "/bin/zsh", "/sbin/jsh", "/sbin/jsh", "/sbin/pfsh", "/sbin/sh", "/usr/bin/bash", + "/usr/bin/csh", "/usr/bin/jsh", "/usr/bin/ksh", "/usr/bin/pfcsh", "/usr/bin/pfksh", "/usr/bin/pfsh", + "/usr/bin/sh", "/usr/bin/tcsh", "/usr/bin/zsh", "/usr/xpg4/bin/sh" ]; + + foreach $shell (@$possible_shells) + { + &push_shell (\@shells, $shell); + } } + else + { + $ifh = &Utils::File::open_read_from_names($shells_file); + + while (<$ifh>) + { + next if &Utils::Util::ignore_line ($_); + chomp; + &push_shell (\@shells, $_); + } - &Utils::File::close_file ($ifh); + &Utils::File::close_file ($ifh); + } return \@shells; } @@ -67,6 +86,9 @@ sub set my ($shells) = @_; my ($buff, $line, $nline); + #SunOS doesn't have /etc/shells + return if ($Utils::Backend::tool{"system"} eq "SunOS"); + $buff = &Utils::File::load_buffer ($shells_file); return unless $buff; diff --git a/Users/Users.pm b/Users/Users.pm index edf6c98..846eeff 100644 --- a/Users/Users.pm +++ b/Users/Users.pm @@ -207,6 +207,7 @@ sub get_profiles_prop_array } } +#FIXME: do not hardcode GIDs like that my $rh_logindefs_defaults = { 'shell' => '/bin/bash', 'group' => -1, @@ -242,6 +243,7 @@ my $logindefs_dist_map = { 'slackware-9.1.0' => $gentoo_logindefs_defaults, 'freebsd-5' => $freebsd_logindefs_defaults, 'suse-9.0' => $gentoo_logindefs_defaults, + 'solaris-2.11' => $gentoo_logindefs_defaults, }; @@ -397,7 +399,7 @@ sub get # we need to make sure that there are 5 elements push @comment, "" while (scalar (@comment) < 5); $line[$COMMENT] = [@comment]; - + $users_hash{$login} = [@line]; } @@ -417,6 +419,9 @@ sub get $login = shift @line; $passwd = shift @line; + # do not add data if the user isn't present + next if (!exists $users_hash{$login}); + $users_hash{$login}[$PASSWD] = $passwd; # FIXME: add the rest of the fields? @@ -474,44 +479,52 @@ sub change_user_chfn { my ($login, $old_comment, $comment) = @_; my ($fname, $office, $office_phone, $home_phone); - my ($command); + my ($command, $str); return if !$login; # Compare old and new data return if (Utils::Util::struct_eq ($old_comment, $comment)); + $str = join (",", @$comment); if ($Utils::Backend::tool{"system"} eq "FreeBSD") { - my ($str); - - $str = join (",", @$comment); $command = "$cmd_pw usermod -n " . $login . " -c \'" . $str . "\'"; } else { - ($fname, $office, $office_phone, $home_phone) = @$comment; + $command = "$cmd_usermod -c \'" . $str . "\' " . $login; + } - $command = "$cmd_chfn" . - " -f \'" . $fname . "\'" . - " -h \'" . $home_phone . "\'"; + &Utils::File::run ($command); +} - if ($Utils::Backend::tool{"platform"} =~ /^debian/ || - $Utils::Backend::tool{"platform"} =~ /^archlinux/) - { - $command .= " -r \'" . $office . "\'" . - " -w \'" . $office_phone . "\'"; - } - else +# modifies /etc/shadow directly, not good practice, +# but better than passing clean passwords around +sub modify_shadow_password +{ + my ($login, $password) = @_; + my ($buffer, $i, @arr); + + $buffer = &Utils::File::load_buffer (@shadow_names); + return if (!$buffer); + $i = 0; + + while ($$buffer[$i]) + { + @arr = split ':', $$buffer[$i], -1; + + if ($arr[0] eq $login) { - $command .= " -o \'" . $office . "\'" . - " -p \'" . $office_phone . "\'"; + $arr[1] = $password; + $$buffer[$i] = join (':', @arr) . "\n"; + last; } - $command .= " $login"; + $i++; } - &Utils::File::run ($command); + &Utils::File::save_buffer ($buffer, @shadow_names); } sub add_user @@ -542,6 +555,22 @@ sub add_user print $pwdpipe $$user[$PASSWD]; &Utils::File::close_file ($pwdpipe); } + elsif ($Utils::Backend::tool{"system"} eq "SunOS") + { + $home_parents = $$user[$HOME]; + $home_parents =~ s/\/+[^\/]+\/*$//; + &Utils::File::run ("$tool_mkdir -p $home_parents"); + + $command = "$cmd_useradd" . + " -d \'" . $$user[$HOME] . "\'" . + " -g \'" . $$user[$GID] . "\'" . + " -s \'" . $$user[$SHELL] . "\'" . + " -u \'" . $$user[$UID] . "\'" . + " \'" . $$user[$LOGIN] . "\'"; + + &Utils::File::run ($command); + &modify_shadow_password ($$user[$LOGIN], $$user[$PASSWD]); + } else { $home_parents = $$user[$HOME]; @@ -606,6 +635,19 @@ sub change_user print $pwdpipe $$new_user[$PASSWD]; &Utils::File::close_file ($pwdpipe); } + elsif ($Utils::Backend::tool{"system"} eq "SunOS") + { + $command = "$cmd_usermod" . + " -d \'" . $$new_user[$HOME] . "\'" . + " -g \'" . $$new_user[$GID] . "\'" . + " -l \'" . $$new_user[$LOGIN] . "\'" . + " -s \'" . $$new_user[$SHELL] . "\'" . + " -u \'" . $$new_user[$UID] . "\'" . + " \'" . $$old_user[$LOGIN] . "\'"; + + &Utils::File::run ($command); + &modify_shadow_password ($$new_user[$LOGIN], $$new_user[$PASSWD]); + } else { $command = "$cmd_usermod" . @@ -675,7 +717,7 @@ sub set { $users{$$i[0]} |= 1; $config_hash{$$i[0]} = $i; - } + } foreach $i (@$old_config) { @@ -703,7 +745,7 @@ sub set { &change_user ($old_config_hash{$i}, $config_hash{$i}); } - } + } } } diff --git a/UsersConfig.pm b/UsersConfig.pm index 3277db5..92054c2 100644 --- a/UsersConfig.pm +++ b/UsersConfig.pm @@ -1,4 +1,3 @@ -#!/usr/bin/env perl #-*- Mode: perl; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- # DBus object for the Users list diff --git a/Utils/File.pm b/Utils/File.pm index 35c05d1..21ef7ca 100644 --- a/Utils/File.pm +++ b/Utils/File.pm @@ -747,6 +747,19 @@ sub join_buffer_lines } } +sub read_joined_lines +{ + my ($file) = @_; + my ($buffer); + + $buffer = &load_buffer ($file); + &join_buffer_lines ($buffer); + + $$buffer[0] =~ s/\n//; + $$buffer[0] =~ s/\\//; + + return $$buffer[0]; +} # --- Command-line utilities --- # diff --git a/Utils/Platform.pm b/Utils/Platform.pm index 1522fb1..00742c3 100644 --- a/Utils/Platform.pm +++ b/Utils/Platform.pm @@ -99,7 +99,9 @@ my $PLATFORM_INFO = { "fedora-3" => [ "Fedora Core", "3", "Heidelberg" ], "fedora-4" => [ "Fedora Core", "4", "Stentz" ], "rpath" => [ "rPath Linux" ], - "ark" => [ "Ark Linux" ] + "ark" => [ "Ark Linux" ], + "solaris-2.11" => [ "Solaris / OpenSolaris", "2.11", "Nevada" ], + "nexenta-1.0" => [ "Nexenta GNU/Solaris", "1.0", "Ellate" ], }; sub ensure_distro_map @@ -144,7 +146,8 @@ sub ensure_distro_map "ubuntu-6.06" => "debian-3.0", "ubuntu-6.10" => "debian-3.0", "vine-3.1" => "vine-3.0", - "vlos-1.2" => "gentoo" + "vlos-1.2" => "gentoo", + "nexenta-1.0" => "solaris-2.11", ); return $metamap{$distro} if ($metamap{$distro}); @@ -153,11 +156,17 @@ sub ensure_distro_map sub check_lsb { - my ($ver, $dist); + my ($ver, $dist, %distmap); + + %distmap = { + "gnu_solaris" => "nexenta" + }; $dist = lc (&Utils::Parse::get_sh ("/etc/lsb-release", "DISTRIB_ID")); $ver = lc (&Utils::Parse::get_sh ("/etc/lsb-release", "DISTRIB_RELEASE")); - + + $dist = $$distmap{$dist} if exists $$distmap{$dist}; + return -1 if ($dist eq "") || ($ver eq ""); return "$dist-$ver"; } @@ -254,24 +263,12 @@ sub check_solaris { my ($fd, $dist); - # - # The file /etc/release is present for solaris-2.6 - # solaris 2.5 does not have the file. Solaris-7.0 and 8.0 have not - # been checked - # - # uname output - # Solaris 2.5: 5.5(.1) - # Solaris 2.6: 5.6 - # Solaris 7: unknown, assume 7.0 - # Solaris 8: unknown, assume 8.0 - # $fd = &Utils::File::run_pipe_read ("uname -r"); return -1 if $fd eq undef; chomp ($dist = <$fd>); &Utils::File::close_file ($fd); - if ($dist =~ /^5\.(\d)/) { return "solaris-2.$1" } - else { if ($dist =~ /^([78])\.\d/) { return "solaris-$1.0" } } + if ($dist =~ /^5\.(\d+)/) { return "solaris-2.$1" } return -1; } |