+#!/usr/bin/perl
+# Helper script for synchronizing /etc/passwd, /etc/group, and /etc/shadow
+
+use common::sense;
+
+my $all = $ARGV[0] eq '--all';
+my @files = ();
+
+print "Syncing /etc/passwd\n";
+open my $p, '<', '/etc/passwd' or die;
+open my $q, '>', '/etc/passwd.new' or die;
+system qw(chmod --reference /etc/passwd /etc/passwd.new);
+system qw(chown --reference /etc/passwd /etc/passwd.new);
+my %sysusers = ();
+while (<$p>) {
+ my @a = split /:/;
+ # FIXME: Hard-wired UIDs
+ if ($a[3] < 65000 || $a[3] >= 65500) {
+ print $q $_;
+ $sysusers{$a[0]} = 1;
+ }
+}
+open my $r, '<', 'etcpasswd' or die;
+while (<$r>) { print $q $_; }
+close $r;
+close $q;
+close $p;
+push @files, 'passwd';
+
+print "Syncing /etc/group\n";
+open my $p, '<', '/etc/group' or die;
+open my $q, '>', '/etc/group.new' or die;
+system qw(chmod --reference /etc/group /etc/group.new);
+system qw(chown --reference /etc/group /etc/group.new);
+while (<$p>) {
+ my @a = split /:/;
+ # FIXME: Hard-wired GIDs
+ if ($a[2] < 65000 || $a[2] >= 65500) {
+ print $q $_;
+ }
+}
+open my $r, '<', 'etcgroup' or die;
+while (<$r>) { print $q $_; }
+close $r;
+close $q;
+close $p;
+push @files, 'group';
+
+if ($all) {
+ print "Syncing /etc/shadow\n";
+ open my $p, '<', '/etc/shadow' or die;
+ open my $q, '>', '/etc/shadow.new' or die;
+ system qw(chmod --reference /etc/shadow /etc/shadow.new);
+ system qw(chown --reference /etc/shadow /etc/shadow.new);
+ while (<$p>) {
+ my @a = split /:/;
+ if ($sysusers{$a[0]}) {
+ print $q $_;
+ }
+ }
+ open my $r, '<', 'etcshadow' or die;
+ while (<$r>) { print $q $_; }
+ close $r;
+ close $q;
+ close $p;
+ push @files, 'shadow';
+}
+
+for my $f (@files) {
+ rename "/etc/$f", "/etc/$f.old" or die "Rename failed: $!\n";
+ rename "/etc/$f.new", "/etc/$f" or die "Rename failed: $!\n";
+}