#!/usr/bin/perl
# DocumentId:	$Id: emuga-usergen.pl 1763 2004-02-09 14:52:06Z ola $
# Author:	$Author: ola $
# Date:		$Date: 2004-02-09 15:52:06 +0100 (mån, 09 feb 2004) $
# Version:	$Revision: 1.4 $
# Summary:
#

###############################################################################
# Changes:
#	2004-01-30 Ola Lundqvist <opal@debian.org>,
#		   Gunnar Bergqvist <gunnar.bergqvist@ttyconsult.se>
#		Rewrite becuase it is a new tool.
###############################################################################

$range = "norange";
$definitionFile = "/etc/emuga/passwd.def";
$passwdTemplateFile = "/etc/emuga/passwd.template";
$shadowTemplateFile = "/etc/emuga/shadow.template";
$passwdFile = "/etc/passwd";
$shadowFile = "/etc/shadow";
$createHomes = 0;

$outPFile = $passwdFile;
$outSFile = $shadowFile;

###############################################################################
############################# USES ############################################
# Changes:
#	2002-03-18 Ola Lundqvist <opal@debian.org>
#		Wrote the uses.
###############################################################################

use File::Copy;
use File::Basename;
use File::Find;

###############################################################################
############################# HELP ############################################
# Changes:
#	2002-03-18 Ola Lundqvist <opal@debian.org>
#		Wrote it.
#	2004-01-30 Ola Lundqvist <opal@debian.org>,
#		   Gunnar Bergqvist <gunnar.bergqvist@ttyconsult.se>
#		Rewrite becuase it is a new tool.
#	2004-02-02 Ola Lundqvist <opal@debian.org>
#		Final testing and modification.
#	2004-02-06 Ola Lundqvist <opal@debian.org>
#		Added create homedir using skel option.
###############################################################################

$help = "
USAGE: emuaga-groupgen [options]

options:
  --outfile file | -o file
		The file to put the output
  -s
		Output to stdout (both passwd and shadow).
  -c		Create a home directory too (using skel from /etc).
  --passwdfile file | -p file
		The original passwd file to generate data from.
  --shadowfile file | -h file
		The original shadow file to generate data from.
  --passwdtemplatefile file
		The template file to use for UIDS and some other things.
  --shadowtemplatefile file
		The template file to use for UIDS and some other things.
  --definitionfile file | -d file
		The definition file to use (for user definitions).
 --dl n
		Set the debug level.
  --ql n
		Set the quit level.
  --help
		Print this help message.

";

###############################################################################
############################# ARGS ############################################
# Desctiption:
#	Argument handling.
# Changes:
#	2002-03-18 Ola Lundqvist <opal@debian.org>
#		Wrote it.
#	2004-01-30 Ola Lundqvist <opal@debian.org>,
#		   Gunnar Bergqvist <gunnar.bergqvist@ttyconsult.se>
#		Rewrite becuase it is a new tool.
#	2004-02-02 Ola Lundqvist <opal@debian.org>
#		Final testing and modification.
#	2004-02-06 Ola Lundqvist <opal@debian.org>
#		Added create homedir using skel option.
###############################################################################

while ($_ = shift @ARGV) {
    if (/^--/) {
	if (/^--dl$/ || /^--debug-level$/) {
	    setDebugLevel(shift @ARGV);
	}
	elsif (/^--ql$/ || /^--quit-level$/) {
	    setQuitLevel(shift @ARGV);
	}
	elsif (/^--help$/) {
            print($help);
	    exit 0;
	}
	elsif (/^--passwdfile$/) {
	    $passwdFile = shift @ARGV;
	    if (length($passwdFile) == 0) {
		die "Empty passwd file name.\n";
	    }
	}
	elsif (/^--shadowfile$/) {
	    $shadowFile = shift @ARGV;
	    if (length($shadowFile) == 0) {
		die "Empty shadow file name.\n";
	    }
	}
	elsif (/^--passwddefinitionfile$/) {
	    $definitionFile = shift @ARGV;
	    if (length($definitionFile) == 0) {
		die "Empty passwd def file name.\n";
	    }
	}
	elsif (/^--passwdtemplatefile$/) {
	    $passwdTemplateFile = shift @ARGV;
	    if (length($passwdTemplateFile) == 0) {
		die "Empty passwd template file name.\n";
	    }
	}
	elsif (/^--shadowtemplatefile$/) {
	    $shadowTemplateFile = shift @ARGV;
	    if (length($shadowTemplateFile) == 0) {
		die "Empty shadow template file name.\n";
	    }
	}
	else {
	    print ("Unknown option $_.\n");
	    exit (1);
	}
    }
    elsif (/^-$/) {
	print(3, "Unknown option '-'.\n");
	exit (1);
    }
    elsif (/^-/) {
	s/^\-//;
	my $t = $_;
	foreach (split //, $t) {
	    if (/p/) {
		$passwdFile = shift @ARGV;
		if (length($passwdFile) == 0) {
		    die "Empty passwd file name.\n";
		}
	    }
	    elsif (/h/) {
		$shadowFile = shift @ARGV;
		if (length($shadowFile) == 0) {
		    die "Empty shadow file name.\n";
		}
	    }
	    elsif (/c/) {
		$createHomes = 1;
	    }
	    elsif (/d/) {
		$definitionFile = shift @ARGV;
	    }
	    elsif (/s/) {
		$outPFile = "-";
		$outSFile = "-";
	    }
	    else {
		print "Unknown option '-$_'.\n";
		exit (1);
	    }
	}
    }
}

require $definitionFile;

if ($UIDS eq "norange") {
    print("You have to specify a UID range in where you are placing your\n".
	  "group definitions.\n");
    exit(0);
}

###############################################################################
############################ The actual program ###############################
# Changes:
#	2002-03-18 Ola Lundqvist <opal@debian.org>
#		Wrote it.
#	2004-01-30 Ola Lundqvist <opal@debian.org>,
#		   Gunnar Bergqvist <gunnar.bergqvist@ttyconsult.se>
#		Rewrite becuase it is a new tool.
#	2004-02-02 Ola Lundqvist <opal@debian.org>
#		Final testing and modification.
#	2004-02-06 Ola Lundqvist <opal@debian.org>
#		Added create homedir using skel option.
###############################################################################
my @P = ( stripUser($passwdFile,1,@UIDS),
	  stripUser($passwdTemplateFile,0,@UIDS) );
# Stripped users in @SU.
my @SU = strippedUsers($passwdFile, @UIDS);
my @S = ( stripShadow($shadowFile,1, @SU),
	  stripShadow($shadowTemplateFile,0,@SU) );
open(P, ">$outPFile") || die "Can not open $outPFile for writing.\n";
open(S, ">$outSFile") || die "Can not open $outSFile for writing.\n";
print P @P;
close(P);
print S @S;
close(S);
# Creates homes if necessary
for $u (@SU) {
    $u =~ s/\n//;
    my $dir = (split(/:/, (stripShadow($passwdTemplateFile,0,($u)))[0]))[5];
    my $uid = (split(/:/, (stripShadow($passwdTemplateFile,0,($u)))[0]))[2];
    my $gid = (split(/:/, (stripShadow($passwdTemplateFile,0,($u)))[0]))[3];
    if (! (-d $dir) ) {
	system("mkdir -p $dir");
	system("rsync -a /etc/skel/ $dir/");
	system("chown -Rf $uid.$gid $dir/");
    }
}

###############################################################################
# Name:		stripUser
# Argument:	passwd file name
#		To strip or to grep.
#		UIDS definition to strip for.
# Return:	a string with the passwd file content.
# Changes:
#	2002-03-18 Ola Lundqvist <opal@debian.org>
#		Wrote it.
#	2004-01-30 Ola Lundqvist <opal@debian.org>,
#		   Gunnar Bergqvist <gunnar.bergqvist@ttyconsult.se>
#		Rewrite becuase it is a new tool.
#	2004-02-02 Ola Lundqvist <opal@debian.org>
#		Final testing and modification.
#	2004-02-06 Ola Lundqvist <opal@debian.org>
#		Fixed a tiny bug.
###############################################################################
sub stripUser($$@) {
    my ($passwdFile, $strip, @iStrip) = @_;
    open (G, $passwdFile);
    my @users = <G>;
    close(G);
    # Strip for all groups defined.
    my (@su) = ();
    foreach my $s (@iStrip) {
	if (length($s) > 0) {
	    if ($strip) {
		@users = grep(!/^[^:]+:[^:]+:$s:/, @users);
	    }
	    else {
		push @su, grep(/^[^:]+:[^:]+:$s:/, @users);
	    }
	}
    }
    if (!$strip) {
	@users = @su;
    }
    return @users;
}

###############################################################################
# Name:		strippedUsers
# Argument:	passwd file name
#		UIDS definition to strip for.
# Return:	an array with the stripped user names.
# Changes:
#	2004-01-30 Ola Lundqvist <opal@debian.org>,
#		   Gunnar Bergqvist <gunnar.bergqvist@ttyconsult.se>
#		Rewrite becuase it is a new tool.
#	2004-02-02 Ola Lundqvist <opal@debian.org>
#		Final testing and modification.
###############################################################################
sub strippedUsers($@) {
    my ($passwdFile, @iStrip) = @_;
    open (G, $passwdFile);
    my @users = <G>;
    close(G);
    my @su = ();
    # Strip for all groups defined.
    foreach my $s (@iStrip) {
	if (length($s) > 0) {
	    push @su, grep(/^[^:]+:[^:]+:$s:/, @users);
	}
    }
    return map { s/:.*//; $_; } @su;
}

###############################################################################
# Name:		stripShadow
# Argument:	shadow file name
#		To strip or to grep.
#		username definition to strip for.
# Return:	a string with the shadow file content.
# Changes:
#	2004-01-30 Ola Lundqvist <opal@debian.org>,
#		   Gunnar Bergqvist <gunnar.bergqvist@ttyconsult.se>
#		Rewrite becuase it is a new tool.
#	2004-02-02 Ola Lundqvist <opal@debian.org>
#		Final testing and modification.
###############################################################################
sub stripShadow($$@) {
    my ($shadowFile, $strip, @uStrip) = @_;
    open (G, $shadowFile);
    my @shadows = <G>;
    close(G);
    # Strip for all groups defined.
    my (@ss) = ();
    foreach my $s (@uStrip) {
	$s =~ s/\n//;
	if (length($s) > 0) {
	    if ($strip) {
		@shadows = grep(!/^$s:/, @shadows);
	    }
	    else {
		push @ss, grep(/^$s:/, @shadows);
	    }
	}
    }
    if (!$strip) {
	@shadows = @ss;
    }
    return @shadows;
}

=head1 NAME

emuga-groupgen - Generate group information.

=head1 USAGE

emuga-groupgen [options]

=head1 DESCRIPTION

Emuga groupgen takes a template, definition and group file and generates
new group information based on that.

=head1 OPTIONS

  --outfile file | -o file
		The file to put the output
  -s
		Output to stdout.
  -c		Create a home directory too (using skel from /etc).
  --passwdfile file | -p file
		The original passwd file to generate data from.
  --shadowfile file | -h file
		The original shadow file to generate data from.
  --passwdtemplatefile file
		The template file to use for UIDS and some other things.
  --shadowtemplatefile file
		The template file to use for UIDS and some other things.
  --definitionfile file | -d file
		The definition file to use (for user definitions).
  --dl n
		Set the debug level.
  --ql n
		Set the quit level.
  --help
		Print this help message.

=head1 AUTHOR

Ola Lundqvist <opal@debian.org>

=head1 SEE ALSO

emuga-target(1)

=cut
