chiark / gitweb /
as used
[id-fixup.git] / runegen
1 #!/usr/bin/perl -w
2 #
3
4 use strict;
5 use IO::Handle;
6
7 my ($passwd,$dashuid,$chown,$phase) = @ARGV;
8 my $offset = 20000;
9 my $find = "find -xdev";
10
11 warn "strips setuid bits!";
12
13 our %undomap;
14 # construct array mapping
15 #   new_id -> old_id
16
17 my $re = '^(\w[^:]*)\:[^:]+\:(\d+)\:';
18
19 sub find_did ($$) {
20     my ($xname,$xid) = @_;
21     # returns the actual uid that source uid xid was (perhaps mistakenly)
22     # mapped to
23     open D, "$passwd-dst" or die $!;
24     while (<D>) {
25         m/$re/o or die "$_ $!";
26         my ($dname,$did) = ($1,$2);
27         return $did if $dname eq $xname;
28     }
29     die $! if D->error;
30     return $xid;
31 }
32
33 open S, "$passwd-src" or die $!;
34 while (<S>) {
35     m/$re/o or die "$_ $!";
36     my ($sname,$sid) = ($1,$2);
37     my $did = find_did($sname,$sid);
38     push @{ $undomap{$did} }, $sid;
39 }
40 die $! if S->error;
41
42 sub mkmap ($$) {
43     my ($in,$out) = @_;
44     printf "$find $dashuid $in -print0 | xargs -0r $chown -- $out\n"
45         or die $!;
46 }
47
48 our @ambigs;
49
50 foreach my $sid (keys %undomap) {
51     my @dids = @{ $undomap{$sid} };
52     next if @dids==1 && $dids[0]==$sid;
53     if ($phase eq '1') {
54         mkmap($sid,$sid+$offset);
55     } elsif ($phase eq '2') {
56         if (@dids==1) {
57             mkmap($sid+$offset,$dids[0]);
58         } else {
59             print "# ambiguous $sid->@dids\n";
60             print "$find $dashuid ".($sid+$offset)." -ls\n"
61                 or die $!;
62         }
63     } elsif ($phase eq '0') {
64         next if @dids==1;
65         push @ambigs, $sid;
66     } else {
67         die "$phase ?";
68     }
69 }
70
71 if ($phase eq '0' && @ambigs) {
72     print "$find \\( ".
73         (join " -o ", map { "$dashuid $_" } @ambigs).
74         " \\) -ls\n"
75         or die $!;
76 }
77
78 close STDOUT or die $!;