home *** CD-ROM | disk | FTP | other *** search
- #!/usr/bin/perl
- #
- # mvids - "moves" uids and gids
- # Tom Christiansen <tchrist@convex.com>
- #
- # usage: mvids [-n] [-f howtomvfile] [starting-dir]
- #
- # Takes list of new user and group ids.
- # Fixes passwd and group files.
- # Traverses local file system starting with starting-dir
- # updating all changed ids
- #
- # -n means don't really change anything
- # -f is if you don't like the default description file name of howtomv
-
-
- # read descriptions from howtomv file with format:
- # type name number
- # e.g.:
- # user tom 1023
- # group staff 200
-
-
- $| = 1;
- $oops = 0;
-
- do 'getopts.pl' || warn "problem doing getopts.pl: $!\n";
-
- do Getopts('dnf:');
-
- $FILE = $opt_f || "howtomv";
-
- $DIR = $opt_d ? "." : "/etc";
-
- $topdir = shift || '/';
-
- die "usage: $0 [-n] [-f howtomv] [starting-dir]\n" if $#ARGV > -1;
-
- die "$topdir: Not a directory" unless -d $topdir;
-
- open FILE || die "Can't open directions file \"$FILE\": $!\n";
- while (<FILE>) {
- s/\s*#.*//;
- next if /^$/;
- unless (/^(user|group)\s+(\w+)\s+(\d+)/) {
- print STDERR "malformed line at line $. of $FILE: $_";
- $oops++; next;
- }
- if ($3 > 32000) {
- print STDERR "$1 $2 has id that's too big ($3)\n";
- $oops++; next;
- }
- if ($3 == 0) {
- print STDERR "Too dangerous to move $1 $2 to 0\n";
- $oops++; next;
- }
- if ($2 eq 'root') {
- print STDERR "You don't really want to move root\n";
- $oops++; $next;
- }
- if ($1 eq 'user') {
- if (defined $n_pwn2i{$2}) {
- print STDERR "Saw user $2 again at line $. of $FILE\n";
- $oops++; next;
- }
- if (defined $n_pwi2n{$3}) {
- print STDERR "Saw uid $3 again at line $. of $FILE\n";
- $oops++; next;
- }
- $uids++;
- $n_pwn2i{$2} = $3;
- $n_pwi2n{$3} = $2;
- } else {
- if (defined $n_grn2i{$2}) {
- print STDERR "Saw group $2 again at line $. of $FILE\n";
- $oops++; next;
- }
- if (defined $n_gri2n{$3}) {
- print STDERR "Saw gid $3 again at line $. of $FILE\n";
- $oops++; next;
- }
- $gids++;
- $n_grn2i{$2} = $3;
- $n_gri2n{$3} = $2;
- }
- }
-
- $PWD = "$DIR/passwd";
- $NPWD = "$PWD.new";
-
- if ($uids) {
- open PWD || die "Can't open $PWD: $!\n";
- open (NPWD, ">$NPWD") || die "Can't create $NPWD: $!\n";
-
- while (<PWD>) {
- ((($name,$uid) = /^(\w+):[^:]*:(\d+):/))
- || die "Bad passwd entry at line $.\n";
- if (defined $n_pwi2n{$uid} && !defined $n_pwn2i{$name}) {
- printf STDERR "Can't move user %s to uid %d -- %s already has it\n",
- $n_pwi2n{$uid}, $uid, $name;
- $oops++;
- next;
- }
- $pwn2i{$name} = $uid;
- s/:$uid:/:$n_pwn2i{$name}:/ if defined $n_pwn2i{$name};
- print NPWD;
- }
- close PWD;
- close NPWD;
-
- foreach $user (keys %pwnam) {
- unless (defined $pwn2i{$user}) {
- print STDERR "Can't move non-existent user $user\n";
- $oops++;
- }
- }
-
- }
-
- if ($gids) {
- $GRP = "$DIR/group";
- $NGRP = "$GRP.new";
- open GRP || die "Can't open $GRP: $!\n";
- open (NGRP , ">$NGRP") || die "Can't create $NGRP: $!\n";
-
- while (<GRP>) {
- ((($name,$gid) = /^(\w+):[^:]*:(\d+):/))
- || die "Bad group entry at line $.\n";
- if (defined $n_gri2n{$gid} && !defined $n_grn2i{$name}) {
- printf STDERR "Can't move gid %s to %d -- %s already has it\n",
- $n_gri2n{$gid}, $gid, $name;
- $oops++;
- next;
- }
- $grn2i{$name} = $gid;
- s/:$gid:/:$n_grn2i{$name}:/ if defined $n_grn2i{$name};
- print NGRP;
- }
- close GRP;
- close NGRP;
-
- foreach $group (keys %grnam) {
- unless (defined $grn2i{$group}) {
- print STDERR "Can't move non-existent group $group\n";
- $oops++;
- }
- }
-
- }
-
- die "$0: $oops error" . ($oops > 1 ? "s" : "").
- " in remapping directions.\n" if $oops;
-
-
- die "$0: no ids to move\n" unless $uids || $gids;
-
- # ok, now do it
-
- open(FIND, "find $topdir \\( -fstype nfs -prune \\) -o -ls |")
- || die "Can't open find pipe";
-
- while (<FIND>) {
- split;
- $uid = $gid = -1;
- ($file, $user, $group) = ($_[11], $_[5], $_[6]);
-
- if (defined $n_pwn2i{$user}) {
- $uid = $n_pwn2i{$user};
- print "changing owner $user of $file from ",
- "$pwn2i{$user} to $n_pwn2i{$user}\n";
- }
- if (defined $n_grn2i{$group}) {
- $gid = $n_grn2i{$group};
- print "changing group $group of $file from ",
- "$grn2i{$group} to $n_grn2i{$group}\n";
- }
-
- if (!$opt_n && ($uid != -1 || $gid != -1)) {
- if (!chown $uid, $gid, $file) {
- printf STDERR "couldn't chown $file to $uid.$gid: $!\n";
- $oops++;
- }
- }
- }
-
- unless ($opt_n) {
- if ($uids) {
- rename($PWD, "$PWD.bak")
- || die "Can't mv $PWD to $PWD.bak: $!\n";
- rename($NPWD, $PWD)
- || die "Can't mv $NPWD to $PWD: $!\n";
- }
- if ($gids) {
- rename($GRP, "$GRP.bak")
- || die "Can't mv $GRP to $GRP.bak: $!\n";
- rename($NGRP, $GRP)
- || die "Can't mv $NGRP to $GRP: $!\n";
- }
- }
-
- exit ($oops != 0);
-