chiark / gitweb /
as used master
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Sun, 4 Aug 2013 16:06:05 +0000 (17:06 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Sun, 4 Aug 2013 16:06:05 +0000 (17:06 +0100)
genrunes [new file with mode: 0755]
runegen [new file with mode: 0755]

diff --git a/genrunes b/genrunes
new file mode 100755 (executable)
index 0000000..18bed6c
--- /dev/null
+++ b/genrunes
@@ -0,0 +1,6 @@
+#!/bin/sh
+set -e
+for phase in 0 1 2; do
+    ./runegen passwd -uid chown $phase >phase-$phase-runes
+    ./runegen group  -gid chgrp $phase >>phase-$phase-runes
+done
diff --git a/runegen b/runegen
new file mode 100755 (executable)
index 0000000..edf9a48
--- /dev/null
+++ b/runegen
@@ -0,0 +1,78 @@
+#!/usr/bin/perl -w
+#
+
+use strict;
+use IO::Handle;
+
+my ($passwd,$dashuid,$chown,$phase) = @ARGV;
+my $offset = 20000;
+my $find = "find -xdev";
+
+warn "strips setuid bits!";
+
+our %undomap;
+# construct array mapping
+#   new_id -> old_id
+
+my $re = '^(\w[^:]*)\:[^:]+\:(\d+)\:';
+
+sub find_did ($$) {
+    my ($xname,$xid) = @_;
+    # returns the actual uid that source uid xid was (perhaps mistakenly)
+    # mapped to
+    open D, "$passwd-dst" or die $!;
+    while (<D>) {
+       m/$re/o or die "$_ $!";
+       my ($dname,$did) = ($1,$2);
+       return $did if $dname eq $xname;
+    }
+    die $! if D->error;
+    return $xid;
+}
+
+open S, "$passwd-src" or die $!;
+while (<S>) {
+    m/$re/o or die "$_ $!";
+    my ($sname,$sid) = ($1,$2);
+    my $did = find_did($sname,$sid);
+    push @{ $undomap{$did} }, $sid;
+}
+die $! if S->error;
+
+sub mkmap ($$) {
+    my ($in,$out) = @_;
+    printf "$find $dashuid $in -print0 | xargs -0r $chown -- $out\n"
+       or die $!;
+}
+
+our @ambigs;
+
+foreach my $sid (keys %undomap) {
+    my @dids = @{ $undomap{$sid} };
+    next if @dids==1 && $dids[0]==$sid;
+    if ($phase eq '1') {
+       mkmap($sid,$sid+$offset);
+    } elsif ($phase eq '2') {
+       if (@dids==1) {
+           mkmap($sid+$offset,$dids[0]);
+       } else {
+           print "# ambiguous $sid->@dids\n";
+           print "$find $dashuid ".($sid+$offset)." -ls\n"
+               or die $!;
+       }
+    } elsif ($phase eq '0') {
+       next if @dids==1;
+       push @ambigs, $sid;
+    } else {
+       die "$phase ?";
+    }
+}
+
+if ($phase eq '0' && @ambigs) {
+    print "$find \\( ".
+       (join " -o ", map { "$dashuid $_" } @ambigs).
+       " \\) -ls\n"
+       or die $!;
+}
+
+close STDOUT or die $!;