The generally accepted low bound is 500. Which goes for both UIDs and GIDs.
As for re-assigning, sounds like a job for PERL or some expertly crafted "find" commands. You could create an index in a 2-dimensional array (or just a flat file) mapping new to old UID and then just spider the mount points in question. Just make sure you heavily test it prior to unlessing it.
benr.
-----Original Message----- From: Jim Davis [mailto:jdavis@cs.arizona.edu] Sent: Wed 4/16/2003 10:43 AM To: toasters@mathworks.com Cc: Subject: Reassigning low UIDs Our Unix-side password files go back to the days of SunOS 3.x (if not before), so we have some users with UIDs less than 100. Nowadays this causes problems with NFS on, eg, Linux boxes that seem to assume any UID under at least 1000 is fair game for placeholder accounts. After struggling with this for a while it looks like it's time for a wholesale UID reassignment for those users.
- what's a "safe" lower bound for UIDs? 1000? 10000? We'd rather not have to do this more than once!
- is there some slick way to reassign UIDs en masse on a filer? We could run 'chown -R ...' on the admin host, but is there a better way?
Jim Davis jdavis@cs.arizona.edu wrote: [...]
- is there some slick way to reassign UIDs en masse on a filer? We could
run 'chown -R ...' on the admin host, but is there a better way?
Be _very_ careful about using "chown -R". In particular, worry about whether it follows symlinks ("chown -h -R" would be safer in Solaris, for example). Also worry about users hard-linking each others' files.
Ben Rockwood BRockwood@homestead-inc.com responds: [...]
As for re-assigning, sounds like a job for PERL or some expertly crafted "find" commands. You could create an index in a 2-dimensional array (or just a flat file) mapping new to old UID and then just spider the mount points in question. Just make sure you heavily test it prior to unlessing it.
I can offer you the following "multichown" Perl script that will do this sort of thing. It does rely on the filing system it is munging over to be static, and it has only been tested under Solaris.
#!/bin/perl
# This program does selective chown/chgrp operations on all inodes # in one or more directory trees. It will often be run as "root".
# There should be one or more option arguments of the form # -owner:NAME1:NAME2 (-o, -user, -u are synonyms of -owner) # -group:NAME1:NAME2 (-g is a synonym of -group) # to specify changing owner or group from NAME1 to NAME2. Users # and groups can be specified by name or by numeric uid/gid.
# The remaining arguments are the path names of the top-level directories # to be searched. (This directory itself is not included in the list of # inodes processed.) Relative path names are allowed provided the PWD # environment variable is set correctly on entry.
%OWNER = (); %GROUP = (); $OWNER = "user" ; $GROUP = "group"; %keys = ( "-owner", *OWNER, "-o", *OWNER, "-user", *OWNER, "-u", *OWNER, "-group", *GROUP, "-g", *GROUP);
while ($ARGV[0] =~ /^-/) { (@name = split(/:/,($arg = shift @ARGV),4)) == 3 && defined ($name = $keys{shift @name}) || die "$0: Invalid option $arg\n"; local(*KTYPE) = $name; for (@name) { next if /^\d+$/; defined($name = &KTYPE) || die "$0: Unknown $KTYPE $_\n"; $_ = $name; } $KTYPE{0+$name[0]} = 1+$name[1]; }
sub OWNER { return scalar getpwnam($_); } sub GROUP { return scalar getgrnam($_); }
keys (%OWNER) + keys (%GROUP) or die "$0: No owner or group substitutions specified\n";
# Prefix remaining arguments with $PWD if appropriate.
undef $prefix; for (@ARGV) { unless (m#^/#) { $prefix = &pwdpath."/" unless $prefix; $_ = $prefix.$_; } }
sub pwdpath { local($pwd) = $ENV{"PWD"}; local($deva,$inoa,$devb,$inob); (($deva,$inoa) = stat(".")) || die "$0: Cannot stat current directory: $!\n"; $pwd =~ m#^/# || die "$0: Invalid environment variable PWD = $pwd\n"; (($devb,$inob) = stat($pwd)) || die "$0: Cannot stat $pwd: $!\n"; ($deva==$devb && $inoa==$inob) || die "$0: Incorrect environment variable PWD = $pwd\n"; return $pwd; }
# Now do the real work passing over the directories.
while (defined ($name = shift @ARGV)) { unless (chdir $name) { warn "Cannot make $name current: $!\n" ; next } unless (opendir(DIR,".")) { warn "Cannot open $name: $!\n" ; next } while ($entry = readdir DIR) { next if $entry eq "." || $entry eq ".."; unless (@stat = lstat $entry) { warn "Unable to stat $name/$entry: $!\n" ; next } $perm = $stat[2]; $type = $perm&0xf000; if ($type==0x4000) { unshift (@ARGV,"$name/$entry"); } $olduid = $stat[4]; $newuid = $OWNER{$olduid}-1; $oldgid = $stat[5]; $newgid = $GROUP{$oldgid}-1; unless ($newuid < 0 && $newgid < 0) { if ($type==0x8000 && ($perm&06000)!=0) { warn "$name/$entry is setuid or setgid - not changed\n"; } elsif ($type==0xa000) { warn "$name/$entry is symlink - not changed\n" } elsif (chown ($newuid, $newgid, $entry)) { printf "%6d %6d -> %6d %6d ",$olduid,$oldgid,$newuid,$newgid; print "$name/$entry\n"; } else { warn "Unable to chown $name/$entry: $!\n" } } } closedir(DIR) }
# End of program