#!/usr/bin/perl
# script to create many user account at once
#   quota-aware

# ----- parameters

my $userhomefilesys;
my $userfile;
my $quotatemplateuser;

if ($#ARGV == 1) {
  $userhomefilesys = $ARGV[0];
  $userfile = $ARGV[1];
  $quotatemplateuser = "";
}
elsif ($#ARGV == 2) {
  $userhomefilesys = $ARGV[0];
  $quotatemplateuser = $ARGV[1];
  $userfile = $ARGV[2];
}
else {
  die "usage: bulkuseradd USERHOMEFILESYSTEM [QUOTATEMPLATEUSER] ",
        "USERDATAFILE\n",
    "        [> SCRIPTFILE]\n",
    "  USERHOMEFILESYSTEM is the filesystem where the user account ",
        "home directories\n",
    "    will be created.\n",
    "  USERDATAFILE is tab-delimited with a header line ",
        "and the following fields:\n",
    "    1 - username\n",
    "    2 - password\n",
    "    3 - full name\n",
    "    4 - group/stream\n",
    "  If quotas are in use, specify QUOTATEMPLATEUSER;\n",
    "    this user's quotas will be copied to the new user accounts.\n",
    "  The output of blukuseradd will be a set of commands\n",
    "    that will add the users, set quotas if appropriate,\n",
    "    and set passwords.\n",
    "  Typically the output is captured to a script file;\n",
    "    the script can be run using the following commands:\n",
    "      chmod 700 SCRIPTFILE;  ./SCRIPTFILE\n";
}

#print "userhomefilesys:  $userhomefilesys\n";
#print "userfile: $userfile\n";
#print "quotatemplateuser: $quotatemplateuser\n";

if ($quotatemplateuser ne "") {
  if (`cut -f2 /etc/mnttab | grep $userhomefilesys | wc -l` == 0) {
          die "$0: user home file system '$userhomefilesys' " ,
                  "is not in /etc/mnttab\n";
  }
  elsif (! -e("$userhomefilesys/quotas")) {
    die "$0: quota template user $quotatemplateuser was specified,\n",
      "but quotas are not turned on for file system $userhomefilesys.\n";
  }
  elsif (`grep '^$quotatemplateuser:' /etc/passwd | wc -l` != 1) {
    die "$0: quota template user $quotatemplateuser not found.\n";
  }
}
elsif (-e("$userhomefilesys/quotas")) {
  die "$0: quotas are turned on for file system $userhomefilesys,\n",
    "but no QUOTATEMPLATEUSER was specified.\n";
}

open(Users,$userfile) or die "$0: Can't open $userfile: $!\n";

# verify format - should be four fields
if (`sed -n 1p $userfile | wc -w` != 4) {
        die "$0: USERDATAFILE must have 4 fields (username, password, ",
                "full name, group\n";
}

# ----- create necessary user groups

# compute different user groups
my @groups = `tail +2 $userfile | cut -f 4 | sed 's/ //g' |
  sed 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/' |
  sort | uniq`;

for my $group (@groups) {
  chomp $group;
  if (`grep '^$group:' /etc/group | wc -l` == 0) {
    print "groupadd $group\n";
  }
}

print "\n";

# ----- next, create user accounts

while (<Users>) {

  # skip the first row (headers)
  if ($. == 1) {
    next;
  }

  # break out the fields
  #   username and group all lower-case
  #   no spaces in group name
  chomp;
  my @fields = split(/\t/);
  my $username = `echo "$fields[0]" |
      sed "s/'//g" |
      sed 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'`;
  chomp $username;
  my $fullname = $fields[2];
  my $stream = $fields[3];
  $stream = `echo $fields[3] | sed 's/ //g' |
      sed 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'`;
  chomp $stream;

  # --- create user
  print "useradd -c \"$fullname\" -g students -G $stream ",
      "-d $userhomefilesys/$username -m $username\n";

  # --- add disk quota
  if ($quotatemplateuser ne "") {
    print "edquota -p $quotatemplateuser $username\n";
  }

  print "\n";
}

#TODO: must be a way to reset file w/o close & re-open
close(Users);
open(Users,$userfile);

print "cp /etc/shadow etc-shadow-orig\n";
print "cp /etc/shadow temppwfile\n";

while (<Users>) {

  # skip the first row (headers)
  if ($. == 1) {
    next;
  }

  chomp;
  my @fields = split(/\t/);
  my $username = `echo "$fields[0]" |
      sed "s/'//g" |
      sed 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'`;
  chomp $username;
  my $password = $fields[1];

  # compute hashed password
  # from http://www.computing.net/linux/wwwboard/forum/28430.html
  my $itoa64 = './01234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ' .
        'abcdefghijklmnopqrstuvwxyz';
  my $salt = "";
  for (1..2) { $salt .= substr($itoa64, rand (length ($itoa64)), 1); }
  my $encryptedpw = crypt ($password, $salt);

  # --- add password
  print "sed '/^$username:/d' temppwfile > tempfile\n";
  print "mv tempfile temppwfile\n";
  print "echo \"$username\:$encryptedpw\:::0::::\" >> temppwfile\n";
}

close(Users);

print "chmod 400 temppwfile\n";

print "\n\n";

print "echo \"### YOU MUST MANUALLY INSPECT temppwfile.\"\n";
print "echo \"### IF IT DOES NOT CONTAIN OBVIOUS ERRORS,\"\n";
print "echo \"### REPLACE /etc/shadow WITH temppwfile:\"\n";
print "echo \"###   cp temppwfile /etc/shadow\"\n";
print "echo \"### NEXT VERIFY ROOT LOGIN.\"\n";
print "echo \"### IF ROOT LOGIN FAILS, RESTORE /etc/shadow:\"\n";
print "echo \"###   cp etc-shadow-orig /etc/shadow\"\n";
