Handle hostnames with upper-case letters
[webmin.git] / net / open-linux-lib.pl
1 # open-linux.pl
2 # Networking functions for openlinux
3
4 $net_scripts_dir = "/etc/sysconfig/network-scripts";
5 $network_config = "/etc/sysconfig/network";
6 $static_route_config = "/etc/sysconfig/network-scripts/ifcfg-routes";
7 $nis_conf = "/etc/nis.conf";
8
9 do 'linux-lib.pl';
10
11 # boot_interfaces()
12 # Returns a list of interfaces brought up at boot time
13 sub boot_interfaces
14 {
15 local(@rv, $f);
16 opendir(CONF, &translate_filename($net_scripts_dir));
17 while($f = readdir(CONF)) {
18         next if ($f !~ /^ifcfg-(\S+)/ || $f eq 'ifcfg-routes' ||
19                  $f =~ /\.sample$/);
20         local (%conf, $b);
21         &read_env_file("$net_scripts_dir/$f", \%conf);
22         $b->{'fullname'} = $conf{'DEVICE'} ? $conf{'DEVICE'} : $1;
23         if ($b->{'fullname'} =~ /(\S+):(\d+)/) {
24                 $b->{'name'} = $1;
25                 $b->{'virtual'} = $2;
26                 }
27         else { $b->{'name'} = $b->{'fullname'}; }
28         $b->{'up'} = ($conf{'ONBOOT'} eq 'yes');
29         $b->{'address'} = $conf{'IPADDR'} ? $conf{'IPADDR'} : "Automatic";
30         $b->{'netmask'} = $conf{'NETMASK'} ? $conf{'NETMASK'} : "Automatic";
31         $b->{'broadcast'} = $conf{'BROADCAST'} ? $conf{'BROADCAST'}
32                                                : "Automatic";
33         $b->{'dhcp'} = $conf{'DYNAMIC'} eq 'dhcp';
34         $b->{'edit'} = ($b->{'name'} !~ /^ppp|plip/);
35         $b->{'desc'} = $conf{'NAME'};
36         $b->{'index'} = scalar(@rv);
37         $b->{'file'} = "$net_scripts_dir/$f";
38         push(@rv, $b);
39         }
40 closedir(CONF);
41 return @rv;
42 }
43
44 # save_interface(&details)
45 # Create or update a boot-time interface
46 sub save_interface
47 {
48 local(%conf);
49 local $name = $_[0]->{'virtual'} ne "" ? $_[0]->{'name'}.":".$_[0]->{'virtual'}
50                                        : $_[0]->{'name'};
51 &lock_file("$net_scripts_dir/ifcfg-$name");
52 &read_env_file("$net_scripts_dir/ifcfg-$name", \%conf);
53 $conf{'DEVICE'} = $name;
54 if ($_[0]->{'dhcp'}) {
55         $conf{'DYNAMIC'} = 'dhcp';
56         }
57 else {
58         $conf{'IPADDR'} = $_[0]->{'address'};
59         delete($conf{'DYNAMIC'});
60         }
61 local($ip1, $ip2, $ip3, $ip4) = split(/\./, $_[0]->{'address'});
62 $conf{'NETMASK'} = $_[0]->{'netmask'};
63 local($nm1, $nm2, $nm3, $nm4) = split(/\./, $_[0]->{'netmask'});
64 $conf{'NETWORK'} = sprintf "%d.%d.%d.%d",
65                         ($ip1 & int($nm1))&0xff,
66                         ($ip2 & int($nm2))&0xff,
67                         ($ip3 & int($nm3))&0xff,
68                         ($ip4 & int($nm4))&0xff;
69 $conf{'BROADCAST'} = $_[0]->{'broadcast'};
70 $conf{'ONBOOT'} = $_[0]->{'up'} ? "yes" : "no";
71 $conf{'NAME'} = $_[0]->{'desc'};
72 &write_env_file("$net_scripts_dir/ifcfg-$name", \%conf);
73 &unlock_file("$net_scripts_dir/ifcfg-$name");
74 }
75
76 # delete_interface(&details)
77 # Delete a boot-time interface
78 sub delete_interface
79 {
80 local $name = $_[0]->{'virtual'} ne "" ? $_[0]->{'name'}.":".$_[0]->{'virtual'}
81                                        : $_[0]->{'name'};
82 &unlink_logged("$net_scripts_dir/ifcfg-$name");
83 }
84
85 # can_edit(what)
86 # Can some boot-time interface parameter be edited?
87 sub can_edit
88 {
89 return $_[0] ne "bootp" && $_[0] ne "mtu";
90 }
91
92 # can_iface_desc([&iface])
93 # Returns 1 if boot-interfaces can have comments
94 sub can_iface_desc
95 {
96 return 1;
97 }
98
99 # valid_boot_address(address)
100 # Is some address valid for a bootup interface
101 sub valid_boot_address
102 {
103 return &check_ipaddress($_[0]);
104 }
105
106 sub get_hostname
107 {
108 local %conf;
109 &read_env_file($network_config, \%conf);
110 if ($conf{'HOSTNAME'}) {
111         return $conf{'HOSTNAME'};
112         }
113 return &get_system_hostname(1);
114 }
115
116 # save_hostname(name)
117 sub save_hostname
118 {
119 local %conf;
120 &system_logged("hostname $_[0] >/dev/null 2>&1");
121 &open_lock_tempfile(HOST, ">/etc/HOSTNAME");
122 &print_tempfile(HOST, $_[0],"\n");
123 &close_tempfile(HOST);
124 &lock_file($network_config);
125 &read_file($network_config, \%conf);
126 $conf{'HOSTNAME'} = $_[0];
127 &write_file($network_config, \%conf);
128 &unlock_file($network_config);
129 undef(@main::get_system_hostname);      # clear cache
130 }
131
132 # get_domainname()
133 sub get_domainname
134 {
135 local $d;
136 &execute_command("domainname", undef, \$d, undef);
137 chop($d);
138 return $d;
139 }
140
141 # save_domainname(domain)
142 sub save_domainname
143 {
144 local %conf;
145 &execute_command("domainname ".quotemeta($_[0]));
146 &read_env_file($network_config, \%conf);
147 if ($_[0]) {
148         $conf{'NISDOMAIN'} = $_[0];
149         }
150 else {
151         delete($conf{'NISDOMAIN'});
152         }
153 &write_env_file($network_config, \%conf);
154 }
155
156 sub routing_config_files
157 {
158 return ( $network_config,
159          map { $_->{'file'} } &boot_interfaces() );
160 }
161
162 sub routing_input
163 {
164 local (%conf, %ifc, $f, $gateway, $gatewaydev);
165 &read_file($network_config, \%conf);
166 local ($gateway, $gatewaydev) = &get_default_gateway();
167
168 # Default router and device
169 print &ui_table_row($text{'routes_default'},
170         &ui_radio("gateway_def", $gateway ? 0 : 1,
171                   [ [ 1, $text{'routes_none'} ],
172                     [ 0, $text{'routes_gateway'}." ".
173                          &ui_textbox("gateway", $gateway, 15)." ".
174                          $text{'routes_device'}." ".
175                          &ui_textbox("gatewaydev", $gatewaydev, 6) ] ]));
176
177 # Forward traffic
178 print &ui_table_row($text{'routes_forward'},
179         &ui_yesno_radio("forward", $conf{'IPFORWARDING'} =~ /yes|true/i));
180
181 # Additional routes script
182 print &ui_table_row($text{'routes_script'},
183         &ui_textarea("script", &read_file_contents($static_route_config),
184                      4, 60));
185 }
186
187 sub parse_routing
188 {
189 local %conf;
190 &lock_file($network_config);
191 &read_file($network_config, \%conf);
192 if ($in{'forward'}) { $conf{'IPFORWARDING'} = 'yes'; }
193 else { delete($conf{'IPFORWARDING'}); }
194 local %ifcs = map { $_->{'fullname'}, 1 } &all_interfaces();
195
196 if (!$in{'gateway_def'}) {
197         &to_ipaddress($in{'gateway'}) ||
198                 &error(&text('routes_edefault', $in{'gateway'}));
199         $ifcs{$in{'gatewaydev'}} ||
200                 &error(&text('routes_edevice', $in{'gatewaydev'}));
201         }
202
203 &set_default_gateway($in{'gateway_def'} ? ( ) :
204                         ( $in{'gateway'}, $in{'gatewaydev'} ) );
205
206 &write_file($network_config, \%conf);
207 &unlock_file($network_config);
208
209 &open_lock_tempfile(SCRIPT, ">$static_route_config");
210 $in{'script'} =~ s/\r//g;
211 &print_tempfile(SCRIPT, $in{'script'});
212 &close_tempfile(SCRIPT);
213 &system_logged("chmod +x $static_route_config");
214 }
215
216 sub os_feedback_files
217 {
218 opendir(DIR, $net_scripts_dir);
219 local @f = readdir(DIR);
220 closedir(DIR);
221 return ( (map { "$net_scripts_dir/$_" } grep { /^ifcfg-/ } @f),
222          $network_config, $static_route_config, $nis_conf, "/etc/resolv.conf",
223          "/etc/nsswitch.conf", "/etc/HOSTNAME" );
224 }
225
226 # apply_network()
227 # Apply the interface and routing settings
228 sub apply_network
229 {
230 &system_logged("(cd / ; /etc/rc.d/init.d/network stop ; /etc/rc.d/init.d/network start) >/dev/null 2>&1");
231 }
232
233 # apply_interface(&iface)
234 # Calls an OS-specific function to make a boot-time interface active
235 sub apply_interface
236 {
237 local $out = &backquote_logged("cd / ; ifup '$_[0]->{'fullname'}' 2>&1 </dev/null");
238 return $? ? $out : undef;
239 }
240
241 # get_default_gateway()
242 # Returns the default gateway IP (if one is set) and device (if set) boot time
243 # settings.
244 sub get_default_gateway
245 {
246 &read_file($network_config, \%conf);
247 opendir(CONF, &translate_filename($net_scripts_dir));
248 local $f;
249 while($f = readdir(CONF)) {
250         next if ($f !~ /^ifcfg-(\S+)/);
251         local %ifc;
252         &read_file("$net_scripts_dir/$f", \%ifc);
253         if (&check_ipaddress($ifc{'GATEWAY'})) {
254                 return ( $ifc{'GATEWAY'}, $ifc{'DEVICE'} );
255                 }
256         }
257 closedir(CONF);
258 return ( );
259 }
260
261 # set_default_gateway([gateway, device])
262 # Sets the default gateway to the given IP accessible via the given device,
263 # in the boot time settings.
264 sub set_default_gateway
265 {
266 opendir(CONF, &translate_filename($net_scripts_dir));
267 local $f;
268 while($f = readdir(CONF)) {
269         next if ($f !~ /^ifcfg-(\S+)/);
270         local %ifc;
271         &lock_file("$net_scripts_dir/$f");
272         &read_file("$net_scripts_dir/$f", \%ifc);
273         if (!$_[0] || $ifc{'DEVICE'} ne $_[1]) {
274                 delete($ifc{'GATEWAY'});
275                 }
276         else {
277                 $ifc{'GATEWAY'} = $_[0];
278                 }
279         &write_file("$net_scripts_dir/$f", \%ifc);
280         &unlock_file("$net_scripts_dir/$f");
281         }
282 closedir(CONF);
283 }
284
285 # supports_address6([&iface])
286 # Returns 1 if managing IPv6 interfaces is supported
287 sub supports_address6
288 {
289 local ($iface) = @_;
290 return 0;
291 }
292
293 1;
294