Handle hostnames with upper-case letters
[webmin.git] / cluster-useradmin / sync.cgi
1 #!/usr/local/bin/perl
2 # sync.cgi
3 # Create missing users and groups on servers
4
5 require './cluster-useradmin-lib.pl';
6 &ReadParse();
7 @hosts = &list_useradmin_hosts();
8 @servers = &list_servers();
9 &ui_print_header(undef, $text{'sync_title'}, "");
10
11 # Work out which hosts to sync on
12 @phosts = &create_on_parse(undef, undef, undef, 1);
13
14 # Build lists of all users and group
15 foreach $h (@hosts) {
16         foreach $u (@{$h->{'users'}}) {
17                 push(@ulist, $u) if (!$doneuser{$u->{'user'}}++);
18                 }
19         foreach $g (@{$h->{'groups'}}) {
20                 push(@glist, $g) if (!$donegroup{$g->{'group'}}++);
21                 }
22         }
23
24 # Find users and groups to sync
25 if ($in{'users_mode'} == 1) {
26         @usync = @ulist;
27         }
28 elsif ($in{'users_mode'} == 2) {
29         map { $usel{$_}++ } split(/\s+/, $in{'usel'});
30         @usync = grep { $usel{$_->{'user'}} } @ulist;
31         }
32 elsif ($in{'users_mode'} == 3) {
33         map { $unot{$_}++ } split(/\s+/, $in{'unot'});
34         @usync = grep { !$unot{$_->{'user'}} } @ulist;
35         }
36 elsif ($in{'users_mode'} == 4) {
37         @usync = grep { (!$in{'uuid1'} || $_->{'uid'} >= $in{'uuid1'}) &&
38                         (!$in{'uuid2'} || $_->{'uid'} <= $in{'uuid2'}) } @ulist;
39         }
40 elsif ($in{'users_mode'} == 5) {
41         local $gid = getgrnam($in{'ugid'});
42         @usync = grep { $_->{'gid'} == $gid } @ulist if (defined($gid));
43         }
44
45 if ($in{'groups_mode'} == 1) {
46         @gsync = @glist;
47         }
48 elsif ($in{'groups_mode'} == 2) {
49         map { $gsel{$_}++ } split(/\s+/, $in{'gsel'});
50         @gsync = grep { $gsel{$_->{'group'}} } @glist;
51         }
52 elsif ($in{'groups_mode'} == 3) {
53         map { $gnot{$_}++ } split(/\s+/, $in{'gnot'});
54         @gsync = grep { !$gnot{$_->{'group'}} } @glist;
55         }
56 elsif ($in{'groups_mode'} == 4) {
57         @gsync = grep { (!$in{'ggid1'} || $_->{'gid'} >= $in{'ggid1'}) &&
58                         (!$in{'ggid2'} || $_->{'gid'} <= $in{'ggid2'}) } @glist;
59         }
60
61 # Setup error handler for down hosts
62 sub add_error
63 {
64 $add_error_msg = join("", @_);
65 }
66 &remote_error_setup(\&add_error);
67
68 # Sync on chosen hosts
69 foreach $host (@phosts) {
70         $add_error_msg = undef;
71         local ($serv) = grep { $_->{'id'} == $host->{'id'} } @servers;
72         print "<b>",&text('sync_on', $serv->{'desc'} ? $serv->{'desc'} :
73                                      $serv->{'host'}),"</b><p>\n";
74         print "<ul>\n";
75
76         # Find missing users and groups
77         local (%usync, %gsync);
78         map { $usync{$_->{'user'}}++ } @{$host->{'users'}};
79         map { $gsync{$_->{'group'}}++ } @{$host->{'groups'}};
80         local @uneed = grep { !$usync{$_->{'user'}} } @usync;
81         local @gneed = grep { !$gsync{$_->{'group'}} } @gsync;
82         if (@uneed || @gneed) {
83                 &remote_foreign_require($serv->{'host'},
84                                         "useradmin", "user-lib.pl");
85                 if ($add_error_msg) {
86                         # Host is down!
87                         print "$add_error_msg<p>\n";
88                         print "</ul>\n";
89                         next;
90                         }
91
92                 # Create missing users
93                 foreach $u (@uneed) {
94                         # Create the user
95                         print &text('sync_ucreate', $u->{'user'}),"<br>\n";
96                         if (!$in{'test'}) {
97                                 &remote_foreign_call($serv->{'host'},
98                                         "useradmin", "create_user", $u);
99                                 push(@{$host->{'users'}}, $u);
100                                 }
101                         print "$text{'udel_done'}<p>\n";
102
103                         local $made_home;
104                         if ($in{'makehome'}) {
105                                 # Create the home directory
106                                 local $exists = &remote_eval($serv->{'host'},
107                                         "useradmin", "-d '$u->{'home'}'");
108                                 if (!$exists) {
109                                         print "$text{'usave_mkhome'}<br>\n";
110                                         if (!$in{'test'}) {
111                                                 local $rv = &remote_eval($serv->{'host'}, "useradmin", "&make_dir('$u->{'home'}', oct('$uconfig{'homedir_perms'}'), 1) && chmod(oct('$uconfig{'homedir_perms'}'), '$u->{'home'}') ? undef : \$!");
112                                                 $rv && &error(&text(
113                                                         'usave_emkdir', $rv));
114
115                                                 $rv = &remote_eval($serv->{'host'}, "useradmin", "chown($u->{'uid'}, $u->{'gid'}, '$u->{'home'}')");
116                                                 $rv || &error(&text(
117                                                         'usave_echown', $rv));
118                                                 }
119                                         $made_home = 1;
120                                         print "$text{'udel_done'}<p>\n";
121                                         }
122                                 }
123
124                         if ($in{'others'}) {
125                                 # Create in other modules on the server
126                                 print "$text{'usave_others'}<br>\n";
127                                 if (!$in{'test'}) {
128                                         $u->{'passmode'} = 2;
129                                         &remote_foreign_call(
130                                                 $serv->{'host'}, "useradmin",
131                                                 "other_modules",
132                                                 "useradmin_create_user", $u);
133                                         }
134                                 print "$text{'udel_done'}<p>\n";
135                                 }
136
137                         if ($in{'copy_files'} && $made_home) {
138                                 # Copy files to new home directory
139                                 local $fconfig = &remote_foreign_config(
140                                                 $serv->{'host'}, "useradmin");
141                                 print "$text{'usave_copy'}<br>\n";
142                                 local $uf = $fconfig->{'user_files'};
143                                 local $gn = getgrgid($u->{'gid'});
144                                 $uf =~ s/\$group/$gn/g;
145                                 $uf =~ s/\$gid/$u->{'gid'}/g;
146                                 &remote_foreign_call($serv->{'host'},
147                                         "useradmin",
148                                         "copy_skel_files", $uf, $u->{'home'},
149                                         $u->{'uid'}, $u->{'gid'})
150                                         if (!$in{'test'});
151                                 print "$text{'udel_done'}<p>\n";
152                                 }
153                         }
154
155                 # Create missing groups
156                 foreach $g (@gneed) {
157                         print &text('sync_gcreate', $g->{'group'}),"<br>\n";
158                         if (!$in{'test'}) {
159                                 &remote_foreign_call($serv->{'host'},
160                                         "useradmin", "create_group", $g);
161                                 push(@{$host->{'groups'}}, $g);
162                                 }
163                         print "$text{'udel_done'}<p>\n";
164                         }
165
166                 # Update in local list
167                 &save_useradmin_host($host);
168                 }
169         else {
170                 print "$text{'sync_insync'}<p>\n";
171                 }
172         print "</ul>\n";
173         }
174 &webmin_log("sync", undef, undef, \%in);
175
176 &ui_print_footer("", $text{'index_return'});
177