Handle hostnames with upper-case letters
[webmin.git] / useradmin / save_group.cgi
1 #!/usr/local/bin/perl
2 # save_group.cgi
3 # Saves or creates a new group
4
5 require './user-lib.pl';
6 require 'timelocal.pl';
7 &error_setup($text{'gsave_err'});
8 &ReadParse();
9
10 if ($in{'delete'}) {
11         # Redirect to deletion page
12         &redirect("delete_group.cgi?group=$in{'old'}");
13         return;
14         }
15
16 # Build list of used GIDs
17 &build_group_used(\%gused);
18
19 # Strip out \n characters in inputs
20 $in{'group'} =~ s/\r|\n//g;
21 $in{'pass'} =~ s/\r|\n//g;
22 $in{'encpass'} =~ s/\r|\n//g;
23 $in{'gid'} =~ s/\r|\n//g;
24
25 &lock_user_files();
26 @glist = &list_groups();
27 if ($in{'old'} ne "") {
28         # get old group
29         @glist = &list_groups();
30         ($ginfo_hash) = grep { $_->{'group'} eq $in{'old'} } @glist;
31         $ginfo_hash || &error($text{'gedit_egone'});
32         %ogroup = %$ginfo_hash;
33         $group{'group'} = $ogroup{'group'};
34         &can_edit_group(\%access, \%ogroup) || &error($text{'gsave_eedit'});
35         }
36 else {
37         # check group name
38         $access{'gcreate'}==1 || &error($text{'gsave_ecreate'});
39         $in{'group'} =~ /^[^:\t]+$/ ||
40                 &error(&text('gsave_ebadname', $in{'group'}));
41         $config{'max_length'} && length($in{'group'}) > $config{'max_length'} &&
42                 &error(&text('gsave_elength', $config{'max_length'}));
43         &my_getgrnam($in{'group'}) &&
44                 &error(&text('gsave_einuse', $in{'group'}));
45         $group{'group'} = $in{'group'};
46         }
47
48 # Validate and save inputs
49 if (!$in{'gid_def'} || $in{'old'} ne '') {
50         # Only do GID checks if not automatic
51         $in{'gid'} =~ /^[0-9]+$/ || &error(&text('gsave_egid', $in{'gid'}));
52         !$access{'lowgid'} || $in{'gid'} >= $access{'lowgid'} ||
53                 &error(&text('usave_elowgid', $access{'lowgid'}));
54         !$access{'higid'} || $in{'gid'} <= $access{'higid'} ||
55                 &error(&text('usave_ehigid', $access{'higid'}));
56         if (!$access{'ggid'} && %ogroup && $ogroup{'gid'} != $in{'gid'}) {
57                 &error($text{'gsave_eggid'});
58                 }
59         if (!$access{'gmultiple'}) {
60                 foreach $og (@glist) {
61                         if ($og->{'gid'} == $in{'gid'} &&
62                             $og->{'group'} ne $ogroup{'group'}) {
63                                 &error(&text('usave_egidused',
64                                              $og->{'group'}, $in{'gid'}));
65                                 }
66                         }
67                 }
68         }
69 elsif ( $in{'gid_def'} eq '1' ) {
70         # Can assign GID here
71         $in{'gid'} = int($config{'base_gid'} > $access{'lowgid'} ?
72                          $config{'base_gid'} : $access{'lowgid'});
73         while($gused{$in{'gid'}}) {
74                 $in{'gid'}++;
75                 }
76         if ($access{'higid'} && $in{'gid'} > $access{'higid'}) {
77                 # Out of GIDs!
78                 &error($text{'gsave_eallgid'});
79                 }
80         }
81
82 elsif ( $in{'gid_def'} eq '2' ) {
83         # Can calculate GID here
84         if ( $config{'gid_calc'} ) {
85             $in{'gid'} = &mkgid($in{'group'});
86         } else {
87             $in{'gid'} = &berkeley_cksum($in{'group'});
88         }
89         &error("Unable to calculate GID, invalid group name specified") if ( $in{'gid'} lt 0 );
90
91         while($used{$in{'gid'}}) {
92                 $in{'gid'}++;
93                 }
94         if ($access{'higid'} && $in{'gid'} > $access{'higid'}) {
95                 # Out of GIDS!
96                 &error($text{'gsave_eallgid'});
97                 }
98         }
99
100 @mems = split(/\r?\n/, $in{'members'});
101 $group{'members'} = join(',', @mems);
102 $group{'gid'} = $in{'gid'};
103
104 $salt = chr(int(rand(26))+65) . chr(int(rand(26))+65);
105 if ($in{'passmode'} == 0) { $group{'pass'} = ""; }
106 elsif ($in{'passmode'} == 1) { $group{'pass'} = $in{'encpass'}; }
107 elsif ($in{'passmode'} == 2) { $group{'pass'} = &unix_crypt($in{'pass'}, $salt); }
108
109 if (%ogroup) {
110         # Force defaults for save options if necessary
111         $in{'chgid'} = !$access{'chgid'} if ($access{'chgid'} != 1);
112         $in{'others'} = !$access{'mothers'} if ($access{'mothers'} != 1);
113
114         # Run the pre-change command
115         &set_group_envs(\%group, 'MODIFY_GROUP');
116         $merr = &making_changes();
117         &error(&text('usave_emaking', "<tt>$merr</tt>")) if (defined($merr));
118
119         if ($group{'gid'} != $ogroup{'gid'} && $in{'chgid'}) {
120                 # Change GID on files if needed
121                 if ($in{'chgid'} == 1) {
122                         # Do all the home directories of users in this group
123                         &change_all_home_groups($ogroup{'gid'}, $group{'gid'},
124                                                 \@mems);
125                         }
126                 else {
127                         # Do all files in this group from the root dir
128                         &recursive_change("/", -1, $ogroup{'gid'},
129                                                -1, $group{'gid'});
130                         }
131                 }
132
133         # Save the group
134         &modify_group(\%ogroup, \%group);
135         }
136 else {
137         # Force defaults for save options if necessary
138         $in{'others'} = !$access{'cothers'} if ($access{'cothers'} != 1);
139
140         # Creating a new group
141         &set_group_envs(\%group, 'CREATE_GROUP');
142         $merr = &making_changes();
143         &error(&text('usave_emaking', "<tt>$merr</tt>")) if (defined($merr));
144
145         &create_group(\%group);
146         }
147 &made_changes();
148 &unlock_user_files();
149
150 # Run other module's scripts
151 if ($in{'others'}) {
152         local $error_must_die = 1;
153         eval {
154                 if (%ogroup) {
155                         &other_modules("useradmin_modify_group",
156                                        \%group, \%ogroup);
157                         }
158                 else {
159                         &other_modules("useradmin_create_group", \%group);
160                         }
161                 };
162         $others_err = $@;
163         }
164
165 delete($in{'pass'});
166 delete($in{'encpass'});
167 &webmin_log(%ogroup ? 'modify' : 'create', 'group', $group{'group'}, \%in);
168
169 # Bounce back to the list, if successful
170 &error(&text('gsave_eothers', $others_err)) if ($others_err);
171 &redirect("index.cgi?mode=groups");
172