Handle hostnames with upper-case letters
[webmin.git] / cluster-useradmin / save_group.cgi
1 #!/usr/local/bin/perl
2 # save_group.cgi
3 # Saves an existing group
4
5 require './cluster-useradmin-lib.pl';
6 &error_setup($text{'gsave_err'});
7 &ReadParse();
8 @hosts = &list_useradmin_hosts();
9 @servers = &list_servers();
10
11 # Get old group
12 foreach $h (@hosts) {
13         foreach $u (@{$h->{'users'}}) {
14                 $exists{$u->{'user'}}++;
15                 }
16         }
17
18 # Strip out \n characters in inputs
19 $in{'group'} =~ s/\r|\n//g;
20 $in{'pass'} =~ s/\r|\n//g;
21 $in{'encpass'} =~ s/\r|\n//g;
22 $in{'gid'} =~ s/\r|\n//g;
23
24 # Validate inputs
25 $in{'gid_def'} || $in{'gid'} =~ /^[0-9]+$/ ||
26         &error(&text('gsave_egid', $in{'gid'}));
27 if ($in{'members_def'} == 1) {
28         @add = split(/\s+/, $in{'membersadd'});
29         foreach $u (@add) {
30                 $exists{$u} || &error(&text('gsave_euser', $u));
31                 }
32         }
33 elsif ($in{'members_def'} == 2) {
34         @del = split(/\s+/, $in{'membersdel'});
35         foreach $u (@del) {
36                 $exists{$u} || &error(&text('gsave_euser', $u));
37                 }
38         }
39
40 # Setup error handler for down hosts
41 sub mod_error
42 {
43 $mod_error_msg = join("", @_);
44 }
45 &remote_error_setup(\&mod_error);
46
47 # Do the changes across all hosts
48 &ui_print_header(undef, $text{'gedit_title'}, "");
49 foreach $host (@hosts) {
50         $mod_error_msg = undef;
51         ($group) = grep { $_->{'group'} eq $in{'group'} } @{$host->{'groups'}};
52         next if (!$group);
53         local ($serv) = grep { $_->{'id'} == $host->{'id'} } @servers;
54         print "<b>",&text('gsave_uon', $serv->{'desc'} ? $serv->{'desc'} :
55                                        $serv->{'host'}),"</b><p>\n";
56         print "<ul>\n";
57         &remote_foreign_require($serv->{'host'}, "useradmin", "user-lib.pl");
58         if ($mod_error_msg) {
59                 # Host is down ..
60                 print &text('gsave_failed', $mod_error_msg),"<p>\n";
61                 print "</ul>\n";
62                 next;
63                 }
64         local @glist = &remote_foreign_call($serv->{'host'}, "useradmin",
65                                             "list_groups");
66         ($group) = grep { $_->{'group'} eq $in{'group'} } @glist;
67         if (!$group) {
68                 }
69         local %ogroup = %$group;
70
71         # Update changed fields
72         $group->{'gid'} = $in{'gid'} if (!$in{'gid_def'});
73         $salt = chr(int(rand(26))+65) . chr(int(rand(26))+65);
74         if ($in{'passmode'} == 0) {
75                 $group->{'pass'} = "";
76                 }
77         elsif ($in{'passmode'} == 1) {
78                 $group->{'pass'} = $in{'encpass'};
79                 }
80         elsif ($in{'passmode'} == 2) {
81                 $group->{'pass'} = &unix_crypt($in{'pass'}, $salt);
82                 }
83         local @mems = split(/,/, $group->{'members'});
84         if (@add) {
85                 @mems = &unique(@mems, @add);
86                 }
87         elsif (@del) {
88                 @mems = grep { &indexof($_, @del) < 0 } @mems;
89                 }
90         $group->{'members'} = join(",", @mems);
91
92         # Run the pre-change command
93         &remote_eval($serv->{'host'}, "useradmin", <<EOF
94 \$ENV{'USERADMIN_GROUP'} = '$group->{'group'}';
95 \$ENV{'USERADMIN_ACTION'} = 'MODIFY_GROUP';
96 EOF
97         );
98         $merr = &remote_foreign_call($serv->{'host'}, "useradmin",
99                                      "making_changes");
100         if (defined($merr)) {
101                 print &text('usave_emaking', "<tt>$merr</tt>"),"<p>\n";
102                 print "</ul>\n";
103                 next;
104                 }
105
106         # Update the group on the server
107         print "$text{'gsave_update'}<br>\n";
108         &remote_foreign_call($serv->{'host'}, "useradmin", "modify_group",
109                              \%ogroup, $group);
110         print "$text{'udel_done'}<p>\n";
111
112         # Make file changes
113         local @ulist;
114         if ($in{'servs'} || $host eq $hosts[0]) {
115                 if ($group->{'gid'} != $ogroup{'gid'} && $in{'chgid'}) {
116                         # Change GID on files if needed
117                         if ($in{'chgid'} == 1) {
118                                 # Do all the home directories of users in
119                                 # this group
120                                 print "$text{'usave_gid'}<br>\n";
121                                 @ulist = &remote_foreign_call($serv->{'host'},
122                                                 "useradmin", "list_users");
123                                 foreach $u (@ulist) {
124                                         if ($u->{'gid'} == $ogroup{'gid'} ||
125                                             &indexof($u->{'user'},@mems) >= 0) {
126                                                 &remote_foreign_call(
127                                                         $serv->{'host'},
128                                                         "useradmin",
129                                                         "recursive_change",
130                                                         $u->{'home'},
131                                                         -1, $ogroup{'gid'},
132                                                         -1, $group->{'gid'});
133                                                 }
134                                         }
135                                 print "$text{'udel_done'}<p>\n";
136                                 }
137                         elsif ($in{'chgid'} == 2) {
138                                 # Do all files in this group from the root dir
139                                 print "$text{'usave_gid'}<br>\n";
140                                 &remote_foreign_call($serv->{'host'},
141                                         "useradmin", "recursive_change", "/",
142                                         -1, $ogroup{'gid'}, -1,$group->{'gid'});
143                                 print "$text{'udel_done'}<p>\n";
144                                 }
145                         }
146                 }
147
148         # Run the post-change command
149         &remote_foreign_call($serv->{'host'}, "useradmin", "made_changes");
150
151         if ($in{'others'}) {
152                 if (&supports_gothers($serv)) {
153                         # Update the group in other modules
154                         print "$text{'usave_mothers'}<br>\n";
155                         &remote_foreign_call($serv->{'host'}, "useradmin",
156                                      "other_modules", "useradmin_modify_group",
157                                      $group, \%ogroup);
158                         print "$text{'udel_done'}<p>\n";
159                         }
160                 else {
161                         # Group syncing not supported
162                         print "$text{'gsave_nosync'}<p>\n";
163                         }
164                 }
165
166         # Update in local list
167         $host->{'groups'} = \@glist;
168         if (@ulist) {
169                 $host->{'users'} = \@ulist;
170                 }
171         &save_useradmin_host($host);
172         print "</ul>\n";
173         }
174 &webmin_log("modify", "group", $group->{'group'}, $group);
175
176 &ui_print_footer("", $text{'index_return'});
177