Handle hostnames with upper-case letters
[webmin.git] / dhcpd / edit_options.cgi
1 #!/usr/local/bin/perl
2 # edit_options.cgi
3 # Edit client options for some subnet, shared net, group, host or global
4
5 require './dhcpd-lib.pl';
6 require './params-lib.pl';
7 &ReadParse();
8 $conf = &get_config();
9
10 %access = &get_module_acl();
11 &error_setup($text{'eacl_aviol'});
12
13 $client = &get_parent_config();
14 push(@parents, $client);
15 foreach $i ($in{'sidx'}, $in{'uidx'}, $in{'gidx'}, $in{'idx'}) {
16         $client = $client->{'members'}->[$i] if ($i ne '');
17         push(@parents, $client);
18         }
19
20 if ($client->{'name'} eq 'subnet') {
21         $title = &text('eopt_subtitle',$client->{'values'}->[0]);
22         $back = $text{'eopt_returnsub'};
23         $backlink = "edit_subnet.cgi";
24         &error("$text{'eacl_np'} $text{'eacl_pss'}") if !&can('r',\%access,$client);
25         }
26 elsif ($client->{'name'} eq 'shared-network') {
27         $title = &text('eopt_snettitle',$client->{'values'}->[0]);
28         $back = $text{'eopt_returnshsub'};
29         $backlink = "edit_shared.cgi";
30         &error("$text{'eacl_np'} $text{'eacl_psn'}") if !&can('r',\%access,$client);
31         }
32 elsif ($client->{'name'} eq 'host') {
33         $title = &text('eopt_hosttitle',$client->{'values'}->[0]);
34         $back = $text{'eopt_returnhost'};
35         $backlink = "edit_host.cgi";
36         &error("$text{'eacl_np'} $text{'eacl_psh'}") if !&can('r',\%access,$client);
37         }
38 elsif ($client->{'name'} eq 'group') {
39         @mc = &find("host", $client->{'members'});
40         $title = &text('eopt_grouptitle',scalar(@mc));
41         $back = $text{'eopt_returngroup'};
42         $backlink = "edit_group.cgi";
43         &error("$text{'eacl_np'} $text{'eacl_psg'}") if !&can('r',\%access,$client);
44         }
45 else {
46         $title = $text{'eopt_alltitle'};
47         $back = $text{'eopt_returnindex'};
48         $backlink = "";
49         &error("$text{'eacl_np'} $text{'eacl_pglob'}") if !$access{'global'};
50         }
51
52 # display
53 $backlink .= "?idx=".$in{'idx'}."&gidx=".$in{'gidx'}."&uidx=".$in{'uidx'}.
54              "&sidx=".$in{'sidx'} if (backlink);
55 &ui_print_header($title, $text{'eopt_header'}, "");
56
57 print "<form action=save_options.cgi method=post>\n";
58 printf "<input type=hidden name=level value='%s'>\n",
59         $in{'global'} ? "global" : $client->{'name'};
60 print "<input type=hidden name=idx value='$in{'idx'}'>\n";
61 print "<input type=hidden name=gidx value='$in{'gidx'}'>\n";
62 print "<input type=hidden name=uidx value='$in{'uidx'}'>\n";
63 print "<input type=hidden name=sidx value='$in{'sidx'}'>\n";
64 print "<table border width=100%>\n";
65 print "<tr $tb> <td><b>$text{'eopt_tabhdr'}</b></td> </tr>\n";
66 print "<tr $cb> <td><table width=100%>\n";
67 @opts = &find("option", $client->{'members'});
68
69 print "<tr>\n";
70 print &option_input($text{'eopt_chost'}, "host-name", \@opts, 3);
71 print &option_input($text{'eopt_defrouters'}, "routers", \@opts, 2);
72 print "</tr>\n";
73
74 print "<tr>\n";
75 print &option_input($text{'eopt_smask'}, "subnet-mask", \@opts, 0);
76 print &option_input($text{'eopt_baddr'}, "broadcast-address", \@opts, 0);
77 print "</tr>\n";
78
79 print "<tr>\n";
80 print &option_input($text{'eopt_domname'}, "domain-name", \@opts, 3);
81 print &option_input($text{'eopt_dnsserv'}, "domain-name-servers", \@opts, 2);
82 print "</tr>\n";
83
84 print "<tr>\n";
85 print &option_input($text{'eopt_domsearch'}, "domain-search", \@opts, 6);
86 print "</tr>\n";
87
88 print "<tr>\n";
89 print &option_input($text{'eopt_timeserv'}, "time-servers", \@opts, 2);
90 print &option_input($text{'eopt_logserv'}, "log-servers", \@opts, 2);
91 print "</tr>\n";
92
93 print "<tr>\n";
94 print &option_input($text{'eopt_swapserv'}, "swap-server", \@opts, 2);
95 print &option_input($text{'eopt_rdpath'}, "root-path", \@opts, 3);
96 print "</tr>\n";
97
98 print "<tr>\n";
99 print &option_input($text{'eopt_nisdom'}, "nis-domain", \@opts, 3);
100 print &option_input($text{'eopt_nisserv'}, "nis-servers", \@opts, 2);
101 print "</tr>\n";
102
103 print "<tr>\n";
104 print &option_input($text{'eopt_fontserv'}, "font-servers", \@opts, 2);
105 print &option_input($text{'eopt_xdmserv'}, "x-display-manager", \@opts, 2);
106 print "</tr>\n";
107
108 print "<tr>\n";
109 print &option_input($text{'eopt_statrouters'}, "static-routes", \@opts, 5);
110 print "</tr>\n";
111
112 print "<tr>\n";
113 print &option_input($text{'eopt_ntpserv'}, "ntp-servers", \@opts, 2);
114 print &option_input($text{'eopt_nbns'}, "netbios-name-servers", \@opts, 2);
115 print "</tr>\n";
116
117 print "<tr>\n";
118 print &option_input($text{'eopt_nbs'}, "netbios-scope", \@opts, 3);
119 print &option_input($text{'eopt_nbntype'}, "netbios-node-type", \@opts, 1);
120 print "</tr>\n";
121
122 print "<tr>\n";
123 print &option_input($text{'eopt_toffset'}, "time-offset", \@opts, 1);
124 print &option_input($text{'plib_serverid'}, "dhcp-server-identifier", \@opts, 3);
125 print "</tr>\n";
126
127 print "<tr>\n";
128 print &option_input($text{'eopt_slpa'}, "slp-directory-agent", \@opts, 2,
129                     $text{'eopt_slpaips'});
130 print "</tr>\n";
131
132 print "<tr>\n";
133 print &option_input($text{'eopt_slps'}, "slp-service-scope", \@opts, 3,
134                     $text{'eopt_slpsonly'});
135 print "</tr>\n";
136
137 if ($config{'dhcpd_version'} >= 3) {
138         # Show option definitions
139         print "<tr> <td colspan=4><hr></td> </tr>\n";
140         @defs = grep { $_->{'values'}->[1] eq 'code' &&
141                        $_->{'values'}->[3] eq '=' } @opts;
142         push(@defs, undef);
143         for($i=0; $i<@defs; $i++) {
144                 $o = $defs[$i];
145                 print "<tr>\n";
146                 print "<td><b>$text{'eopt_def'}</b></td> <td nowrap colspan=3>\n";
147                 print "$text{'eopt_dname'}\n";
148                 printf "<input name=dname_$i size=15 value='%s'>\n",
149                         $o->{'values'}->[0];
150                 print "$text{'eopt_dnum'}\n";
151                 printf "<input name=dnum_$i size=4 value='%s'>\n",
152                         $o->{'values'}->[2];
153                 print "$text{'eopt_dtype'}\n";
154                 my $a=scalar(@{$o->{'values'}})-1;
155                 printf "<input name=dtype_$i size=40 value='%s'>\n",
156                         join(" ",@{$o->{'values'}}[4..$a]);
157                 print "</td> </tr>\n";
158                 }
159
160         # Find option definitions at higher levels
161         %optdef = ( );
162         foreach $p (@parents) {
163                 @popts = &find("option", $p->{'members'});
164                 @pdefs = grep { $_->{'values'}->[1] eq 'code' &&
165                                 $_->{'values'}->[3] eq '=' } @popts;
166                 foreach $o (@pdefs) {
167                         $optdef{$o->{'values'}->[0]} = $o
168                                 if ($o->{'values'}->[0]);
169                         }
170                 }
171
172         # Show values for custom options
173         if (keys %optdef) {
174                 @custom = grep { $optdef{$_->{'values'}->[0]} &&
175                                  $_->{'values'}->[1] ne 'code' } @opts;
176                 push(@custom, undef);
177                 push(@custom, undef) if (@custom%2 == 1);
178                 for($i=0; $i<@custom; $i++) {
179                         $o = $custom[$i];
180                         print "<tr> <td><b>$text{'eopt_custom'}</b></td>\n";
181                         print "<td nowrap colspan=3>$text{'eopt_cname'}\n";
182                         local ($ov, @v) = @{$o->{'values'}};
183                         print &ui_select("cname_$i", $ov,
184                                 [ [ "", "&nbsp;" ],
185                                   sort { $a cmp $b } keys %optdef ],
186                                 1, 0, $ov ? 1 : 0);
187                         print "$text{'eopt_cval'}\n";
188                         print &ui_textbox("cval_$i", join(" ", @v), 40);
189                         print "</td> </tr>\n";
190                         }
191                 }
192         }
193 else {
194         # Show custom numeric options
195         print "<tr> <td colspan=4><hr></td> </tr>\n";
196         @custom = grep { $_->{'values'}->[0] =~ /^option-(\S+)$/ &&
197                          $_->{'values'}->[1] ne 'code' } @opts;
198         push(@custom, undef);
199         push(@custom, undef) if (@custom%2 == 1);
200         for($i=0; $i<@custom; $i++) {
201                 $o = $custom[$i];
202                 print "<tr>\n" if ($i%2 == 0);
203                 print "<td><b>$text{'eopt_custom'}</b></td>\n";
204                 print "<td nowrap>$text{'eopt_cnum'}\n";
205                 local ($ov, @v) = @{$o->{'values'}};
206                 printf "<input name=cnum_$i size=4 value='%s'>\n",
207                         $ov =~ /^option-(\S+)$/ ? $1 : '';
208                 print "$text{'eopt_cval'}\n";
209                 printf "<input name=cval_$i size=15 value='%s'></td>\n",
210                         join(" ", @v);
211                 print "</tr>\n" if ($i%2 != 0);
212                 }
213         }
214
215 if ($in{'global'}) {
216         # Display options for subnets and hosts too
217         print "<tr> <td colspan=4><hr></td> </tr>\n";
218         print "<tr>\n";
219         print &choice_input($text{'egroup_nchoice'}, "use-host-decl-names",
220                             $conf, $text{'yes'}, "on", $text{'no'}, "off",
221                             $text{'default'}, "");
222         &display_params($conf, "global");
223         }
224
225 print "</table></td></tr></table>\n";
226 print "<input type=submit value=\"$text{'save'}\"></form>\n"
227         if &can('rw',\%access,$client);
228 &ui_print_footer($backlink, $back);
229
230 # option_input(text, name, &config, type, [initial-boolean])
231 # types values: 0  - IP address
232 #               1  - Integer
233 #               2  - IP address list
234 #               3  - String
235 #               4  - Yes/no flag
236 #               5  - IP address pairs
237 #               6  - String list
238 sub option_input
239 {
240 local($rv, $v, $i);
241 for($i=0; $i<@{$_[2]}; $i++) {
242         if ($_[2]->[$i]->{'values'}->[0] eq $_[1]) {
243                 $v = $_[2]->[$i];
244                 last;
245                 }
246         }
247 $rv = "<td><b>$_[0]</b></td>\n";
248 if ($_[3] == 5 || $_[3] == 6 || $_[4]) { $rv .= "<td colspan=3 nowrap>"; }
249 else { $rv .= "<td nowrap>"; }
250 $rv .= sprintf "<input type=radio name=$_[1]_def value=1 %s> $text{'default'}\n",
251         $v ? "" : "checked";
252 $rv .= sprintf "<input type=radio name=$_[1]_def value=0 %s> ",
253         $v ? "checked" : "";
254 local @vl = $v ? @{$v->{'values'}} : ();
255 @vl = @vl[1..$#vl];
256 local $bool;
257 if ($_[4]) {
258         $bool = shift(@vl);
259         }
260 if ($_[3] == 0) {
261         $rv .= "<input name=$_[1] size=15 value=\"$vl[0]\">\n";
262         }
263 elsif ($_[3] == 1) {
264         $rv .= "<input name=$_[1] size=4 value=\"$vl[0]\">\n";
265         }
266 elsif ($_[3] == 2) {
267         @vl = map { s/,//g; $_ } grep { $_ ne "," } @vl;
268         $rv .= "<input name=$_[1] size=20 value=\"".join(" ", @vl)."\">\n";
269         }
270 elsif ($_[3] == 3) {
271         local $str = &oct_to_string($vl[0]);
272         $rv .= "<input name=$_[1] size=20 value=\"$str\">\n";
273         }
274 elsif ($_[3] == 4) {
275         $rv .= sprintf "<input name=$_[1] value=1 %s> Yes\n",
276                         $vl[0] eq "1" ? "checked" : "";
277         $rv .= sprintf "<input name=$_[1] value=0 %s> No\n",
278                         $vl[0] eq "0" ? "checked" : "";
279         }
280 elsif ($_[3] == 5) {
281         @vl = grep { $_ ne "," } @vl;
282         $rv .= "<input name=$_[1] size=50 value=\"";
283         for($i=0; $i<@vl; $i+=2) {
284                 $rv .= " " if ($i);
285                 $rv .= $vl[$i].",".$vl[$i+1];
286                 }
287         $rv .= "\">\n";
288         }
289 elsif ($_[3] == 6) {
290         @vl = map { s/,//g; $_ } grep { $_ ne "," } @vl;
291         $rv .= "<input name=$_[1] size=50 value=\"".join(" ", @vl)."\">\n";
292         }
293 if ($_[4]) {
294         $rv .= &ui_checkbox($_[1]."_bool", 1, $_[4], lc($bool) eq "true");
295         }
296 $rv .= "</td>\n";
297 return $rv;
298 }
299
300 sub oct_to_string
301 {
302 local @b = split(/:/, $_[0]);
303 local $rv;
304 foreach $b (@b) {
305         if ($b !~ /^[A-z0-9]{1,2}$/) {
306                 # Wasn't actually in octet format after all.
307                 return $_[0];
308                 }
309         $rv .= chr(hex($b));
310         }
311 return $rv;
312 }
313