3 # Update, create or delete a shared network
5 require './dhcpd-lib.pl';
6 require './params-lib.pl';
8 &lock_file($config{'dhcpd_conf'});
9 ($par, $sha, $indent) = &get_branch('sha', $in{'new'});
10 $parconf = $par->{'members'};
13 %access = &get_module_acl();
14 &error_setup($text{'eacl_aviol'});
16 &error("$text{'eacl_np'} $text{'eacl_pdn'}")
17 if !&can('rw', \%access, $sha, 1);
19 elsif ($in{'options'}) {
20 &error("$text{'eacl_np'} $text{'eacl_psn'}")
21 if !&can('r', \%access, $sha);
24 &error("$text{'eacl_np'} $text{'eacl_pin'}")
25 unless &can('c', \%access, $sha) && &can('rw', \%access, $par);
27 if($access{'uniq_sha'}) {
28 foreach $s (&find("shared-network", &get_config())) {
29 &error("$text{'eacl_np'} $text{'eacl_uniq'}")
30 if lc $s->{'values'}->[0] eq lc $in{'name'};
35 &error("$text{'eacl_np'} $text{'eacl_pun'}")
36 if !&can('rw', \%access, $sha);
41 # Redirect to client options
42 &redirect("edit_options.cgi?idx=$in{'idx'}");
47 &error_setup($text{'sshared_faildel'});
50 &error_setup($text{'sshared_failsave'});
51 $in{'name'} =~ /^\S+$/ ||
52 &error($text{'sshared_invalidsname'});
53 $sha->{'values'} = [ $in{'name'} ];
54 $sha->{'comment'} = $in{'desc'};
57 # Move hosts, groups and subnets into or out of this shared network
58 @wasin = &find("host", $sha->{'members'});
59 foreach $hn (split(/\0/, $in{'hosts'})) {
60 if ($hn =~ /(\d+),(\d+)/) {
61 push(@nowin, $parconf->[$2]->{'members'}->[$1]);
62 $nowpr{$parconf->[$2]->{'members'}->[$1]} =
65 elsif ($hn =~ /(\d+),/) {
66 push(@nowin, $parconf->[$1]);
67 $nowpr{$parconf->[$1]} = $par;
69 if ($nowin[$#nowin]->{'name'} ne "host") {
70 &error($text{'sgroup_echanged'});
73 @wasgin = &find("group", $sha->{'members'});
74 foreach $gn (split(/\0/, $in{'groups'})) {
75 if ($gn =~ /(\d+),(\d+)/) {
76 push(@nowgin, $parconf->[$2]->{'members'}->[$1]);
77 $nowgpr{$parconf->[$2]->{'members'}->[$1]} =
80 elsif ($gn =~ /(\d+),/) {
81 push(@nowgin, $parconf->[$1]);
82 $nowgpr{$parconf->[$1]} = $par;
84 if ($nowgin[$#nowgin]->{'name'} ne "group") {
85 &error($text{'sgroup_echanged'});
88 @wasuin = &find("subnet", $sha->{'members'});
89 foreach $un (split(/\0/, $in{'subnets'})) {
90 if ($un =~ /(\d+),(\d+)/) {
91 push(@nowuin, $parconf->[$2]->{'members'}->[$1]);
92 $nowupr{$parconf->[$2]->{'members'}->[$1]} =
95 elsif ($un =~ /(\d+),/) {
96 push(@nowuin, $parconf->[$1]);
97 $nowupr{$parconf->[$1]} = $par;
99 if ($nowuin[$#nowuin]->{'name'} ne "subnet") {
100 &error($text{'sgroup_echanged'});
104 &error_setup($text{'eacl_aviol'});
105 foreach $h (&unique(@wasin, @nowin)) {
106 $was = &indexof($h, @wasin) != -1;
107 $now = &indexof($h, @nowin) != -1;
109 # per-host ACLs for new or updated hosts
110 if ($was != $now && !&can('rw', \%access, $h)) {
111 &error("$text{'eacl_np'} $text{'eacl_pun'}");
114 # Move out of the shared network
115 &save_directive($sha, [ $h ], [ ], 0);
116 &save_directive($par, [ ], [ $h ], 0);
118 elsif ($now && !$was) {
119 # Move into the shared network (maybe from another)
120 &save_directive($nowpr{$h}, [ $h ], [ ], 0);
121 &save_directive($sha, [ ], [ $h ], 1);
124 foreach $g (&unique(@wasgin, @nowgin)) {
125 $was = &indexof($g, @wasgin) != -1;
126 $now = &indexof($g, @nowgin) != -1;
128 # per-group ACLs for new or updated groups
129 if ($was != $now && !&can('rw', \%access, $g)) {
130 &error("$text{'eacl_np'} $text{'eacl_pun'}");
133 # Move out of the shared network
134 &save_directive($sha, [ $g ], [ ], 0);
135 &save_directive($par, [ ], [ $g ], 0);
137 elsif ($now && !$was) {
138 # Move into the shared network (maybe from another)
139 &save_directive($nowgpr{$g}, [ $g ], [ ], 0);
140 &save_directive($sha, [ ], [ $g ], 1);
143 foreach $u (&unique(@wasuin, @nowuin)) {
144 $was = &indexof($u, @wasuin) != -1;
145 $now = &indexof($u, @nowuin) != -1;
147 # per-subnet ACLs for new or updated subnetss
148 if ($was != $now && !&can('rw', \%access, $u)) {
149 &error("$text{'eacl_np'} $text{'eacl_pun'}");
152 # Move out of the shared network
153 &save_directive($sha, [ $u ], [ ], 0);
154 &save_directive($par, [ ], [ $u ], 0);
155 if ($par->{'name'} eq "shared-network") {
159 elsif ($now && !$was) {
160 # Move into the shared network (maybe from another)
161 &save_directive($nowupr{$u}, [ $u ], [ ], 0);
162 &save_directive($sha, [ ], [ $u ], 1);
163 if ($nowupr{$u}->{'name'} eq "shared-network") {
164 &check_subnets($nowupr{$u});
168 &check_subnets($sha);
171 if (!$in{'delete'}) {
175 # Add this shared net
176 &save_directive($par, [ ], [ $sha ], 0);
180 &save_directive($par, [ $sha ], [ $sha ], 0);
187 if ($in{'hosts'} eq "" && $in{'groups'} eq "" && $in{'subnets'} eq "") {
188 &save_directive($par, [ $sha ], [ ], 0);
192 &unlock_file($config{'dhcpd_conf'});
193 &redirect("confirm_delete.cgi?idx=$in{'idx'}\&type=0");
197 &unlock_file($config{'dhcpd_conf'});
198 &webmin_log($in{'delete'} ? 'delete' : $in{'new'} ? 'create' : 'modify',
199 'shared', $sha->{'values'}->[0], \%in);
202 # check whether thist shared network contains any subnet
206 @subnets = &find("subnet", $_[0]->{'members'});
208 &error_setup($text{'sshared_failsave'});
209 &error(&text('sshared_nosubnet', $_[0]->{'values'}->[0]));
213 # force hosts and groups to follow subnets
216 local(@subnets, $max, $u, $i);
217 @subnets = &find("subnet", $_[0]->{'members'});
219 foreach $u (@subnets) {
220 $max = $u->{'index'} > $max ? $u->{'index'} : $max;
222 for ($i = 0; $i < $max; $i++) {
223 $u = $_[0]->{'members'}->[$i];
224 if ($u->{'name'} eq "host" || $u->{'name'} eq "group") {
225 # move to the end of list
226 &save_directive($_[0], [ $u ], [ ], 0);
227 &save_directive($_[0], [ ], [ $u ], 0);