#!/usr/bin/perl
#*********************************************************************
#   Copyright (C) International Business Machines  Corp., 2003
#
#   This program is free software;  you can redistribute it and/or modify
#   it under the terms of the GNU General Public License as published by
#   the Free Software Foundation; either version 2 of the License, or
#   (at your option) any later version.
#
#   This program is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY;  without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
#   the GNU General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with this pronram;  if not, write to the Free Software
#   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
#
#
#  FILE   : passwd01
#
#  PURPOSE: Tests that the data in /etc/passwd is not modifiable
#             in the cases where it should not be.
#
#  SETUP: This script requires perl, as well as the Expect module
#           for perl.  The script must be run by "root". 
#
#  HISTORY:
#    03/03 originated by Dustin Kirkland (k1rkland@us.ibm.com)
#
#*********************************************************************

use Expect;
use strict;
use warnings;

require "utils.plib";

my $username1 = "pd_user1";
my $initial_password1 = "ltp_test_pass";
my $initial_encrypted_password1 = "\\\$1\\\$1yzzszzz\\\$7P9AphbzAN43pTktT\/kpp\/";
my $username2 = "pd_user2";
my $initial_password2 = "ltp_test_pass";
my $initial_encrypted_password2 = "\\\$1\\\$1yzzszzz\\\$7P9AphbzAN43pTktT\/kpp\/";

my @test = (
#           [ exit_code, description_of_test, command_to_execute ]
            [1, "passwd on a non-existant user", "passwd null"],                     # 0
            [1, "passwd on some other user", "passwd $username2"],                   # 1
            [1, "passwd change other user finger info", "passwd -f $username2"],     # 2
            [1, "passwd change own home directory", "passwd -h $username1"],         # 3
            [1, "passwd change other user home directory", "passwd -h $username2"],  # 4
            [1, "passwd delete own password", "passwd -d $username1"],               # 5
            [1, "passwd delete other user password", "passwd -d $username2"],        # 6
            [1, "passwd lock own account", "passwd -l $username1"],                  # 7
            [1, "passwd lock other user account", "passwd -l $username2"],           # 8
            [1, "passwd unlock own account", "passwd -u $username1"],                # 9 
            [1, "passwd unlock other user account", "passwd -u $username2"],         # 10
            [1, "passwd expire own account", "passwd -e $username1"],                # 11
            [1, "passwd expire other user account", "passwd -e $username2"],         # 12
            [1, "passwd set own minimum", "passwd -n 5 $username1"],                 # 13
            [1, "passwd set other user minimum", "passwd -n 5 $username1"],          # 14
            [1, "passwd set own maximum", "passwd -x 5 $username1"],                 # 15
            [1, "passwd set other user maximum", "passwd -x 5 $username2"],          # 16
            [1, "passwd warn own account", "passwd -w 5 $username1"],                # 17
            [1, "passwd warn other user", "passwd -w 5 $username2"],                 # 18
            [0, "passwd view own passwd attributes", "passwd -S"],                   # 19
            [1, "passwd view other user passwd attributes", "passwd -S $username2"], # 20
            [1, "passwd view all user passwd attributes", "passwd -Sa"],             # 21

           );
my @result;
my $exit_code = 0;
my %ARGV;
foreach $_ (@ARGV) {
  $ARGV{$_} = 1;
}


#################
# Begin Testing #
#################

print("========================================================================\n");
print("Begin execution of passwd01\n");
print("Tests that the data in /etc/passwd is not modifiable in the cases where it should not be.\n");
print("========================================================================\n");

print("Username1: [$username1]\n");
print("Password2: [$initial_password1]\n");
print("Username1: [$username2]\n");
print("Password2: [$initial_password2]\n");


for (my $i=0; $i<@test; $i++) {
  if ((@ARGV) && (!$ARGV{$i})) {
    next;
  }
# Create the users for testing purposes
# Set the users' initial passwords
  $Expect::Log_Stdout = 0;
  create_user($username1);
  set_encrypted_password($username1, $initial_encrypted_password1);
  create_user($username2);
  set_encrypted_password($username2, $initial_encrypted_password2);
  $Expect::Log_Stdout = 1;

# Set the system time ahead 2 days
  my $current_time = advance_system_time(2);

  print("\n-> Test \#$i : Trying $test[$i][1] for user [$username1]: `$test[$i][2]`\n");
  my $status = run_as_user($username1, $initial_password1, $test[$i][2]); 
  my $lower = $status / 256;
  my $upper = $status % 256;
  $result[$i] = "==> Test \#$i : ";
  if (($upper == 0) && ($lower == $test[$i][0])) {
    $result[$i] .= "PASS ($test[$i][1])\n";
  } else {
    $result[$i] .= "FAIL ($test[$i][1])\n *** Test \#$i expected exit code [$test[$i][0]] but got [$lower]\n";
    $exit_code = 1;
  }
  print($result[$i]);

# Delete the user that was created for this tests
  $Expect::Log_Stdout = 0;
  delete_user($username1);
  delete_user($username2);
  $Expect::Log_Stdout = 1;

  revert_system_time($current_time);

}

###############
# End Testing #
###############

# Print rolled up results
print("\nSummary of Results\n");
foreach my $result (@result) {
  if ($result) {
    print($result);
  }
}

print("========================================================================\n");
print("End execution of passwd01\n");
print("========================================================================\n");

exit $exit_code;
