Viewing file: save_subnet.cgi (6.25 KB) -rwxr-xr-x Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
#!/usr/bin/perl # save_subnet.cgi # Update, create or delete a subnet
require './dhcpd-lib.pl'; require './params-lib.pl'; &ReadParse(); &lock_file($config{'dhcpd_conf'}); ($par, $sub, $indent, $npar, $nindent) = get_branch('sub', $in{'new'}); $parconf = $par->{'members'};
# check acls %access = &get_module_acl(); &error_setup($text{'eacl_aviol'}); if ($in{'delete'}) { &error("$text{'eacl_np'} $text{'eacl_pds'}") if !&can('rw', \%access, $sub, 1); } elsif ($in{'options'}) { &error("$text{'eacl_np'} $text{'eacl_pss'}") if !&can('r', \%access, $sub); } elsif ($in{'new'}) { &error("$text{'eacl_np'} $text{'eacl_pis'}") unless &can('c', \%access, $sub) && &can('rw', \%access, $par) && (!$npar || &can('rw', \%access, $npar)); # restrict duplicates if ($access{'uniq_sub'}) { foreach $s (&get_subnets()) { &error("$text{'eacl_np'} $text{'eacl_uniq'}") if lc $s->{'values'}->[0] eq lc $in{'network'}; } } } elsif (!$in{'leases'}) { &error("$text{'eacl_np'} $text{'eacl_pus'}") unless &can('rw', \%access, $sub) && (!$npar || &can('rw', \%access, $npar)); }
# save if ($in{'options'}) { # Redirect to client options &redirect("edit_options.cgi?sidx=$in{'sidx'}&idx=$in{'idx'}"); exit; } elsif ($in{'leases'}) { # Redirect to lease list for subnet &redirect("list_leases.cgi?network=$sub->{'values'}->[0]&netmask=$sub->{'values'}->[2]"); exit; } else { if ($in{'delete'}) { &error_setup($text{'ssub_faildel'}); if ($par->{'name'} eq "shared-network") { @subnets = &find("subnet", $par->{'members'}); if (@subnets < 2) { &error(&text('ssub_nosubnet', $par->{'values'}->[0])); } } } else { &error_setup($text{'ssub_failsave'}); # Validate and save inputs &to_ipaddress($in{'network'}) || &error("'$in{'network'}' $text{'ssub_invalidsubaddr'}"); &check_ipaddress($in{'netmask'}) || &error("'$in{'netmask'}' $text{'ssub_invalidnmask'}"); $oldnetwork = $sub->{'values'}->[0]; $sub->{'values'} = [ $in{'network'}, "netmask", $in{'netmask'} ]; }
@wasin = &find("host", $sub->{'members'}); foreach $hn (split(/\0/, $in{'hosts'})) { if ($hn =~ /(\d+),(\d+)/) { push(@nowin, $parconf->[$2]->{'members'}->[$1]); $nowpr{$parconf->[$2]->{'members'}->[$1]} = $parconf->[$2]; } elsif ($hn =~ /(\d+),/) { push(@nowin, $parconf->[$1]); $nowpr{$parconf->[$1]} = $par; } if ($nowin[$#nowin]->{'name'} ne "host") { &error($text{'sgroup_echanged'}); } } @wasgin = &find("group", $sub->{'members'}); foreach $gn (split(/\0/, $in{'groups'})) { if ($gn =~ /(\d+),(\d+)/) { push(@nowgin, $parconf->[$2]->{'members'}->[$1]); $nowgpr{$parconf->[$2]->{'members'}->[$1]} = $parconf->[$2]; } elsif ($gn =~ /(\d+),/) { push(@nowgin, $parconf->[$1]); $nowgpr{$parconf->[$1]} = $par; } if ($nowgin[$#nowgin]->{'name'} ne "group") { &error($text{'sgroup_echanged'}); } }
&error_setup($text{'eacl_aviol'}); foreach $h (&unique(@wasin, @nowin)) { $was = &indexof($h, @wasin) != -1; $now = &indexof($h, @nowin) != -1;
# per-host ACLs for new or updated hosts if ($was != $now && !&can('rw', \%access, $h)) { &error("$text{'eacl_np'} $text{'eacl_pus'}"); } if ($was && !$now) { # Move out of the subnet &save_directive($sub, [ $h ], [ ], $indent); &save_directive($par, [ ], [ $h ], $indent); } elsif ($now && !$was) { # Move into the subnet (maybe from another subnet) &save_directive($nowpr{$h}, [ $h ], [ ], $indent); &save_directive($sub, [ ], [ $h ], $indent + 1); } } foreach $g (&unique(@wasgin, @nowgin)) { $was = &indexof($g, @wasgin) != -1; $now = &indexof($g, @nowgin) != -1;
# per-group ACLs for new or updated groups if ($was != $now && !&can('rw', \%access, $g)) { &error("$text{'eacl_np'} $text{'eacl_pus'}"); } if ($was && !$now) { # Move out of the subnet &save_directive($sub, [ $g ], [ ], $indent); &save_directive($par, [ ], [ $g ], $indent); } elsif ($now && !$was) { # Move into the subnet (maybe from another subnet) &save_directive($nowgpr{$g}, [ $g ], [ ], $indent); &save_directive($sub, [ ], [ $g ], $indent + 1); } }
if (!$in{'delete'}) { &error_setup($text{'ssub_failsave'}); for($i=0; defined($low = $in{"range_low_$i"}); $i++) { next if (!$low); $hi = $in{"range_hi_$i"}; $dyn = $in{"range_dyn_$i"}; &check_ipaddress($low) || &error("'$low' $text{'ssub_invalidipr'}"); !$hi || &check_ipaddress($hi) || &error("'$hi' $text{'ssub_invalidipr'}"); $rng = { 'name' => 'range', 'values' => [ ($dyn ? "dynamic-bootp" : ()), $low, ($hi ? $hi : ()) ] }; push(@rng, $rng); } &save_directive($sub, "range", \@rng, 1); $sub->{'comment'} = $in{'desc'}; &parse_params($sub, 0);
if (!npar || $in{'assign'} > 0 && $npar->{'name'} ne "shared-network") { &error($text{'sgroup_echanged'}); } if ($in{'new'}) { # save acl for new network &save_dhcpd_acl('rw','sub',\%access,$in{'network'}); # Add to the end of the parent structure &save_directive($npar, [ ], [ $sub ], $nindent); } elsif ($par eq $npar) { # Update the subnet in the current parent &save_directive($par, [ $sub ], [ $sub ], $nindent); if ($in{'network'} ne $oldnetwork) { # Fix the ACL &drop_dhcpd_acl('sub', \%access, $oldnetwork); &save_dhcpd_acl('rw','sub',\%access, $in{'network'}); } } else { # Move the subnet if ($par->{'name'} eq "shared-network") { @subnets = &find("subnet", $par->{'members'}); if (@subnets < 2) { &error(&text('ssub_nosubnet', $par->{'values'}->[0])); } } &save_directive($par, [ $sub ], [ ], 0); &save_directive($npar, [ ], [ $sub ], $nindent); } } } &flush_file_lines(); if ($in{'delete'}) { # Delete this subnet if ($in{'hosts'} eq "" && $in{'groups'} eq "") { &drop_dhcpd_acl('sub', \%access, $sub->{'values'}->[0]); &save_directive($par, [ $sub ], [ ], 0); &flush_file_lines(); } else { &unlock_file($config{'dhcpd_conf'}); &redirect("confirm_delete.cgi?sidx=$in{'sidx'}&idx=$in{'idx'}" ."\&type=1"); exit; } } &unlock_file($config{'dhcpd_conf'}); &webmin_log($in{'delete'} ? 'delete' : $in{'new'} ? 'create' : 'modify', 'subnet', "$sub->{'values'}->[0]/$sub->{'values'}->[2]", \%in);
&redirect($in{'ret'} eq "shared" ? "edit_shared.cgi?idx=$in{'sidx'}" : "");
|