Handle hostnames with upper-case letters
[webmin.git] / dhcpd / save_group.cgi
1 #!/usr/local/bin/perl
2 # save_group.cgi
3 # Update, create or delete a group
4
5 require './dhcpd-lib.pl';
6 require './params-lib.pl';
7 &ReadParse();
8 &lock_file($config{'dhcpd_conf'});
9 ($par, $group, $indent, $npar, $nindent) = get_branch('grp', $in{'new'});
10 $parconf = $par->{'members'};
11
12 # check acls
13 %access = &get_module_acl();
14 &error_setup($text{'eacl_aviol'});
15 if ($in{'delete'}) {
16         &error("$text{'eacl_np'} $text{'eacl_pdg'}")
17                 if !&can('rw', \%access, $group, 1);
18         }
19 elsif ($in{'options'}) {
20         &error("$text{'eacl_np'} $text{'eacl_psg'}")
21                 if !&can('r', \%access, $group);
22         }
23 elsif ($in{'new'}) {
24         &error("$text{'eacl_np'} $text{'eacl_pig'}")
25                 unless &can('c', \%access, $group) && 
26                                 &can('rw', \%access, $par) &&
27                                 (!$npar || &can('rw', \%access, $npar));
28         }
29 else {
30         &error("$text{'eacl_np'} $text{'eacl_pug'}")
31                 unless !$npar || &can('rw', \%access, $npar);
32         # for new and updated groups - per-host acls see below    
33         }
34 # save
35 if ($in{'options'}) {
36         # Redirect to client options
37         &redirect("edit_options.cgi?sidx=$in{'sidx'}&uidx=$in{'uidx'}&idx=$in{'idx'}");
38         exit;
39         }
40 else {
41         &error_setup($in{'delete'} ? $text{'sgroup_faildel'} :
42                                       $text{'sgroup_failsave'});
43
44         # Move hosts into or out of this group
45         @wasin = &find("host", $group->{'members'});
46         foreach $hn (split(/\0/, $in{'hosts'})) {
47                 if ($hn =~ /(\d+),(\d+)/) {
48                         push(@nowin, $parconf->[$2]->{'members'}->[$1]);
49                         $nowpr{$parconf->[$2]->{'members'}->[$1]} =
50                                 $parconf->[$2];
51                         }
52                 elsif ($hn =~ /(\d+),/) {
53                         push(@nowin, $parconf->[$1]);
54                         $nowpr{$parconf->[$1]} = $par;
55                         }
56                 if ($nowin[$#nowin]->{'name'} ne "host") {
57                         &error($text{'sgroup_echanged'});
58                         }
59                 }
60
61         &error_setup($text{'eacl_aviol'});
62         foreach $h (&unique(@wasin, @nowin)) {
63                 $was = &indexof($h, @wasin) != -1;
64                 $now = &indexof($h, @nowin) != -1;
65
66                 # per-host ACLs for new or updated hosts
67                 if ($was != $now && !&can('rw', \%access, $h)) {
68                         &error("$text{'eacl_np'} $text{'eacl_pug'}");
69                         }
70                 if ($was && !$now) {
71                         # Move out of the group
72                         &save_directive($group, [ $h ], [ ], $indent);
73                         &save_directive($par, [ ], [ $h ], $indent);
74                         }
75                 elsif ($now && !$was) {
76                         # Move into the group (maybe from another group)
77                         &save_directive($nowpr{$h}, [ $h ], [ ], $indent);
78                         &save_directive($group, [ ], [ $h ], $indent + 1);
79                         }
80                 }
81
82         if (!$in{'delete'}) {
83                 # Validate and save inputs
84                 &save_choice("use-host-decl-names", $group, $indent+1);
85                 $group->{'comment'} = $in{'desc'};
86                 &parse_params($group, $indent+1);
87
88                 &error_setup($text{'sgroup_failsave'});
89                 @partypes = ( "", "shared-network", "subnet" );
90                 if (!$npar || $in{'assign'} > 0 && $npar->{'name'} ne $partypes[$in{'assign'}]) {
91                         if ($in{'jsquirk'}) {
92                                 &error($text{'sgroup_invassign'});
93                                 }
94                         else {
95                                 &redirect("edit_group.cgi?assign=".$in{'assign'}.
96                                         "&idx=".$in{'idx'}."&uidx=".$in{'uidx'}.
97                                         "&sidx=".$in{'sidx'});
98                                 exit;
99                                 }
100                         }
101                 if ($in{'new'}) {
102                         # create this new group
103                         &save_directive($npar, [ ], [ $group ], $nindent);
104                         }
105                 elsif ($par eq $npar) {
106                         # update this group - is it really necessary ?
107                         &save_directive($par, [ $group ], [ $group ], $nindent);
108                         }
109                 else {
110                         # move this group
111                         &save_directive($par, [ $group ], [ ], 0);
112                         &save_directive($npar, [ ], [ $group ], $nindent);
113                         }
114                 }
115         }
116 &flush_file_lines();
117 if ($in{'delete'}) {
118         # Delete this group
119         if ($in{'hosts'} eq "") {
120                 &save_directive($par, [ $group ], [ ], 0);
121                 &flush_file_lines();
122                 }
123         else {
124                 &unlock_file($config{'dhcpd_conf'});
125                 &redirect("confirm_delete.cgi?sidx=$in{'sidx'}&uidx=$in{'uidx'}".
126                         "&idx=$in{'idx'}=&type=2");
127                 }
128         }
129 &unlock_file($config{'dhcpd_conf'});
130 @count = &find("host", $group->{'members'});
131 &webmin_log($in{'delete'} ? 'delete' : $in{'new'} ? 'create' : 'modify',
132             'group', join(",", map { $_->{'values'}->[0] } @count), \%in);
133 if ($in{'ret'} eq "subnet") {
134         $retparms = "sidx=$in{'sidx'}&idx=$in{'uidx'}";
135         }
136 elsif ($in{'ret'} eq "shared") {
137         $retparms = "idx=$in{'sidx'}";
138         }
139 &redirect( $in{'ret'} ? "edit_$in{'ret'}.cgi?$retparms" : "");