[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: slakware to debian.



> I would like to translate the /etc/passwd of slakware to debian. But there
> are around 300 users, and doing it by hand is such a tedious thing!
> Someone could help?

Hi,

I just did this myself.  I wrote a Perl script to do it.  It worked
for us.

When the script finds a file that it can't map to the new password
file (or group file---they're both different), I had it print a
message and make it owned by me ("harlan").  You'll want to change
this to something else, obviously.  (For this purpose I'm modifying
this version (without testing the modifications) by adding the
$defowner and $defgroup variables at the top of the file.  In theory
you could change those to whatever you want and the program will run.
In practice I probably made a typo.)

Another thing it does is replace the group "users" with a group that
is the same as the name of the owner of the file, since that's what
Debian is doing now.

I'm providing this as-is.  I used this as an exercise, since I had
just started to learn Perl.  I intended to run it once and throw it
away.  It doesn't represent ideal software engineering.  It's not
intended for general use.  Its formatting will look best if you use
4-space tabs.  If you don't know how to modify it to fit your use,
don't use it.  How's that for a disclaimer? :)

Good luck,

--
Pete Harlan
pete@mymenus.com

#!/usr/bin/perl -w
#
# passwd-convert -- translates a file tree so all files have uig/gid
# appropriate for a new /etc/passwd file, when they were created under
# an old one.
#
# Begun 2/11/97 by Pete Harlan, pete@mymenus.com.
# 

$defowner = "harlan";
$defgroup = "harlan";

#
# Get Arguments
#
@ARGV == 5 or helpAndDie ();
($startdir, $oldpwfname, $oldgroupfname, $newpwfname, $newgroupfname) =
														@ARGV [0, 1, 2, 3, 4];

#
# Read files.
#
readOldPasswdFile	($oldpwfname	);
readOldGroupFile	($oldgroupfname	);
readNewPasswdFile	($newpwfname	);
readNewGroupFile	($newgroupfname	);

# 
# Process all files in current directory.
#

chdir $startdir
	or die "Unable to chdir to $startdir: $!.\n";
procDir (".", $startdir);

#
# Done.
#
exit 0;


sub procDir
{
	my ($dirname, $pathname) = @_;
	my @fnames;

	chdir $dirname
		or die "Unable to chdir to $dirname: $!.\n";
print "chdir $dirname\n";

	opendir (DIR, ".")
		or die "Error opening $dirname as directory: $!.\n";

	@fnames = readdir DIR;

	foreach $fname (@fnames)
	{
		if ($fname eq "." or $fname eq "..")
		{
			next;	# infinite loops have their place, but not here
		}

		procFname ($fname, $pathname . "/" . $dirname);
	}

	closedir (DIR);

	chdir "..";
print "chdir ..\n";
}


sub procFname
{
	my ($fname, $pathname) = @_;
	my ($mode, $uid, $gid, $username, $groupname);

	# Get the owner/groupid of the file.
	($ignore, $ignore, $mode, $ignore, $uid, $gid, $ignore) = lstat $fname;

	if (!defined ($gid))
	{
		warn "Hey: $pathname/$fname failed lstat: $!\n";
		return;
	}

	# If the userid wasn't in the old passwd file, make me own it.
	if (!defined ($username = $oldUidToUname {$uid}))
	{
		print "$pathname/$fname: Had uid $uid, converting to $defowner.\n";
		$username = $defowner;
	}

	# If the username isn't in the new passwd file, make me own it.
	if (!defined ($newUid = $unameToNewUid {$username}))
	{
		print "$pathname/$fname: No new user for $username, ",
												"converting to $defowner.\n";
		$newUid = $unameToNewUid {$username = $defowner};
	}

	# If the groupid wasn't in the old group file, make $defgroup the group.
	if (!defined ($groupname = $oldGidToGname {$gid}))
	{
		print "$pathname/$fname: Had gid $gid, converting to $defgroup.\n";
		$groupname = $defgroup;
	}

	# If the old group was "users", use the username of the owner.
	if ($groupname eq "users")
	{
		$groupname = $username;
	}

	# If the group name isn't in the new group file, make $defgroup the group.
	if (!defined ($newGid = $gnameToNewGid {$groupname}))
	{
		print "$pathname/$fname: No group for $groupname, ",
												"converting to $defgroup.\n";
		$newGid = $gnameToNewGid {$groupname = $defgroup};
	}

	# Perform the actual chown.
	chown ($newUid, $newGid, $fname) == 1
		or die "Unable to chown $pathname/$filename: $!.\n";
print "chown ($newUid, $newGid, $fname)\n";
	
	# If it's not a link, and it's a directory, recurse.
	if ((! -l _) and -d _)
	{
		procDir ($fname, $pathname);
	}
}


sub readOldPasswdFile ($)
{
	my ($fname) = @_;

	myopen (OLD, $fname);

	while (<OLD>)
	{
		chomp;
		($username, $pwd, $uid, $ignore) = split ":";

		$oldUidToUname {$uid} = $username;
	}
	close (OLD) or die "Can't close $fname: $!\n";
}


sub readOldGroupFile
{
	my ($fname) = @_;

	myopen (OLDG, $fname);

	while (<OLDG>)
	{
		chomp;
		($groupname, $ignore, $groupid, $ignore) = split ":";

		$oldGidToGname {$groupid} = $groupname;
	}
	close (OLDG);
}
	

sub readNewPasswdFile ($)
{
	my ($fname) = @_;

	myopen (NEW, $fname);
	while (<NEW>)
	{
		chomp;
		($username, $pwd, $uid, $ignore) = split ":";
		
		$unameToNewUid {$username} = $uid;
	}
	close (NEW) or die "Whoops! Couldn't close $fname: $!\n";
}


sub readNewGroupFile
{
	my ($fname) = @_;

	myopen (NEWG, $fname);

	while (<NEWG>)
	{
		chomp;
		($groupname, $ignore, $gid, $ignore) = split ":";

		$gnameToNewGid {$groupname} = $gid;
	}
	close (NEWG);
}
	

sub helpAndDie
{
	die "Usage: $0 <startdir> <oldpwfile> <oldgroupfile> ",
											"<newpwfile> <newgroupfile>\n";
}


sub myopen
{
	my ($fref, $fname) = @_;
	open ($fref, $fname) or die "Error opening $fname for reading: $!\n";
}


Reply to: