From: Ian Jackson Date: Sun, 4 Aug 2013 16:06:05 +0000 (+0100) Subject: as used X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?p=id-fixup.git;a=commitdiff_plain;h=refs%2Fheads%2Fmaster as used --- 22c9fb34ac6b54d0fad3f8edcfa76a6241903ea0 diff --git a/genrunes b/genrunes new file mode 100755 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 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 () { + 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 () { + 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 $!;