eval 'exec perl -x $0 ${1+"$@"}' # -*-perl-*-
  if 0;
#!perl -w
#
# ======================================================================
# This file is Copyright 1998,1999 by the Purdue Research Foundation and
# may only be used under license.  For terms of the license, see the
# file named COPYRIGHT included with this software release.
# AAFID is a trademark of the Purdue Research Foundation.
# All rights reserved.
# ======================================================================
#
# AAFID2 system
# Agent name:        PasswdFilesChecker
# Agent description: checks the password file(s), as supplied in MyPasswFile
# Author:            Penka Vassileva Markova
#
# History of modifications:
# 
# Known bugs:
# 
# Things to do:
# 
# Future work:
# 
# Suggestions made by people:
# 
# Generated automatically by ../bin/makeagent.pl on Tue Sep  7 23:55:52 1999.
# 
###### AUTOMATICALLY GENERATED FILE --- DO NOT EDIT ##########
#

# 10 "PasswdFilesChecker.aas"
package PasswdFilesChecker;

# Version number
# 12 "PasswdFilesChecker.aas"
$VERSION=eval {1.0}; $VERSION=$VERSION;

# Agent parameters
%PARAMETERS=(
             Description        => "checks the password file(s), as supplied in MyPasswFile",
             CheckPeriod        => eval {10},

             FiltersNeeded => {  }
            );

# Package loading
use AAFID::Agent;
use AAFID::Log;
use AAFID::Common;


use vars qw (
             @ISA
             $VERSION
             %PARAMETERS
            );

# Define the superclass.
 @ISA=qw(AAFID::Agent);

=head1 PasswdFilesChecker



=cut

# Preamble code


# Provide an Init function.
sub Init {
  my $self=checkref(shift);
# 17 "PasswdFilesChecker.aas"
  $self->Log_activate("debug");
  $max_status = 10 ;
  $min_status =  0 ;

  $Params{MyPasswFile}{ '/etc/passwd'}={'file'} ;

  $Params{MyWeights}={} ;
  $Params{MyWeights}={  blank_lines => 1,
			not_enough_fields =>1,
			not_only_ld_usr =>1,
			only_digits_user =>1,
			no_passwd =>7,
			negat_uid => 3,
			nonnumeric_uid => 3, 
			root_nonroot => 10,
			negat_gid => 3,
			nonnumeric_gid => 3,
			bad_home => 2,
			unknown_shell => 5,
			users_more =>2,
			not_opened => 5,
                    ,
                   } ;
  $Params{MyRoots}{'root'} = 1;
  $Params{MyShells}{'/bin/csh'} = 1;
  return $self;
}

# The Check function.
sub Check {
  my $self=checkref(shift);
# 44 "PasswdFilesChecker.aas"
  my $self=checkref(shift);
  my $message="" ;
  my $status = $min_status ;
  my $PASSWD ;
  foreach $file( sort keys %{$Params{MyPasswFile}})
{ 
  $message.= "FILE $file => ";
  my $opened;
  my (  $blank_lines,  $not_enough_fields, $not_only_ld_usr,$only_digits_user,$no_passwd,$negat_uid,$nonnumeric_uid,$root_nonroot,$negat_gid,$nonnumeric_gid,$bad_home,$unknown_shell,$users_more,$not_opened ) = 0;

  $PASSWD = 'PASSWD' ;

  if ( $Params{MyPasswFile} eq "not_file")
        { $opened = ( open ( $PASSWD, `$file`)) && (defined($PASSWD));}
   else
        {$opened = ( (-e $file) && ( (open( $PASSWD, "< $file"))) && (defined ($PASSWD)));}

   unless ( $opened )
	 { $status = $Params{Weights}{not_opened}; $message = "Couldn't open $file  ";
	   goto END_CHECK_PASSWD_FILE; }
	}  
 
 
#users in different files would not constitute a douplicate
    my $users_once={};
    my $users_more={} ;  
    my $blank_lines = 0;

    while ( $line = <$PASSWD>) {
print "$line";
        next if $line =~ m/^[-+]/;    # skip YP lines

        if ( $line =~ m/^\s*/ )
        {  $blank_lines++;  next ;}

        my ($user,$passwd,$uid,$gid,$gcos,$home,$shell) = split /':'/, $line;
 
        if (@_ != 7)
        { $not_enough_fields++; next; }

        if ( defined ($users_once{$user}) ) 
        { $users_more{$user} = 1; }  
        else 
        { $users_once{$user} = 1; }  
            
        if ( $user !~ m/^[A-Za-z0-9]+$/ )
        { $status += $Params{MyWeights}{not_only_ld_usr} ; $not_only_ld_usr.= "$user, ";}

        if ( $user =~ /^\d+$/ )
        { $status += $Params{MyWeights}{only_digits_user} ; $only_digits_user.= "$user, ";}

        unless ($passwd || ( $passwd eq "")) 
        { $status += $Params{MyWeights}{no_passwd} ; $no_passwd.= "$user, ";}

        if ($uid !~ /^\d+$/) {
            if ($uid < 0) 
                { $status+= $Params{MyWeights}{negat_uid} ; $negat_uid.= "$user, ";}
       
        else 
            { $status+= $Params{MyWeights}{nonnumeric_uid} ; $nonnumeric_uid.= "$user, ";}

        if ( $uid == 0 && undef ( $params{MyRoots}{$user} ) )
           { $status+= $Params{MyWeights}{root_nonroot} ; $root_nonroot.= "$user, ";}


        if ($gid !~ /^\d+$/) {
            if ($gid < 0) 
                { $status+= $Params{MyWeights}{negat_gid} ; $negat_gid.= "$gid: $user, ";}
        } 
        else 
            { $status+= $Params{MyWeights}{nonnumeric_gid} ; $nonnumeric_gid.= "$gid: $user, ";}

        unless  ( $home =~ m:^/: )
            { $status+= $Params{MyWeights}{bad_home} ; $bad_home.= "$home: $user, ";}

        if ( undef ( $params{MyShells}{$shell} ) )
           { $status+= $Params{MyWeights}{unknown_shell} ; $unknown_shell.= "$shell: $user, ";}
    }

close $PASSWD ;  

END_CHECK_PASSWD_FILE:

  unless ( $blank_lines <= 0 )
        { $status += $blank_lines*$Params{MyWeights}{blank_lines}; $message.= "Blank lines: $blank_lines; ";}

  unless ( $not_enough_fields <= 0 )
        { $status += $not_enough_fields*$Params{MyWeights}{not_enough_fields};
          $message.= "Lines with incorrect number of fields: $not_enough_fields; " ;}

  unless ( $not_only_ld_usr eq "" ) {
        $message.= "User names containing other than digits and letters: $not_only_ld_usr; "};

  $message.= "User names containing only digits: $only_digits_user; " unless ( $only_digits_user eq "" );
  $message.= "Users with no password: $no_passwd; " unless ( $no_passwd eq "" );
  $message.= "Negative user ID: $negat_uid; " unless ( $negat_uid eq "" );
  $message.= "Not numeric user ID: $nonnumeric_uid; " unless ( $nonnumeric_uid eq "" );
  $message.= "Unauthorized users with 0 uid: $root_nonroot; " unless ( $root_nonroot eq "" );
  $message.= "Negative group ID: $negat_gid; " unless ( $negat_gid eq "" );
  $message.= "Not numeric group ID: $nonnumeric_gid; " unless ( $nonnumeric_uid eq "" );
  $message.= "Bad user home: $bad_home; " unless ( $bad_home eq "" );
  $message.= "Unknown shell: $unknown_shell; " unless ( $unknown_shell eq "" );

  if ( ${%users_more} > 0)
        {
        $status += ${%users_more}*$Params{MyWeights}{users_more};
        $message.= "Duplicate users: ";
        foreach $u ( keys %users_more )
        {$message.= "$u, "}
        }

  chop $message; chop $message ; $message.=".";
 
}
  if ( $status > $max_status ) 
      { $status = $max_status; } 

  return ($status, $message);



#======================================================================================
}
# Agent commands

sub command_ROOTS_DELETE_ALL {
  my $self=checkref(shift);
  my ($message, %p)=@_;
  if (1) {
    
# 196 "PasswdFilesChecker.aas"
	  $Params{MyRoots} = {};
  $self->Log('debug', "Removing ALL entries from roots list \n");
    # By default, return undef
    return undef;
  }
}

sub command_CHANGE_WEIGHT_FIELDS {
  my $self=checkref(shift);
  my ($message, %p)=@_;
  if (exists($p{Info}) && 1) {
    my $Info = $p{Info};
# 167 "PasswdFilesChecker.aas"
  my @list = splitList($Info);
  my $data_name = shift (@list ) ;
  my $value = pop @list ;
  $Params{MyWeights}{$data_name} = shift (@list) ;
  $self->Log('debug', "Changing the values for $data_name\n");
    # By default, return undef
    return undef;
  }
}

sub command_DELETE_FILES {
  my $self=checkref(shift);
  my ($message, %p)=@_;
  if (exists($p{Info}) && 1) {
    my $Info = $p{Info};
# 272 "PasswdFilesChecker.aas"
  my @list = splitList($Info);

  foreach $list( @list )
  {
	 delete $Params{MyPasswFile}{$list};
  }
  $self->Log('debug', "Removing files from the password files list\n");
    # By default, return undef
    return undef;
  }
}

sub command_SHELLS_LIST {
  my $self=checkref(shift);
  my ($message, %p)=@_;
  if (1) {
    
# 228 "PasswdFilesChecker.aas"
  my $list="";
  foreach $current( keys %{$Params{MyShells}})
	{
	  $list.= $current.", ";
	}
  $self->Log('debug', "Providing a list with the approved shells \n"); 
 return { APPROVED_SHELLS => $list };
#=============================================================================
    # By default, return undef
    return undef;
  }
}

sub command_ADD_FILE {
  my $self=checkref(shift);
  my ($message, %p)=@_;
  if (exists($p{Info}) && 1) {
    my $Info = $p{Info};
# 237 "PasswdFilesChecker.aas"
    my @list = split(/', *'/,$Info);
    if ( scalar @list <1 ) { @list =  $Info;}
    my $file_name = shift (@list ) ;
    my $value = "file";# default 
    if ( scalar @list > 0 ){ $value = shift(@list);
    $Params{MyPasswFile}{$file_name}= $value ;
    }
    $self->Log('debug', "Adding password file $file_name\n");
    # By default, return undef
    return undef;
  }
}

sub command_ROOTS_DELETE {
  my $self=checkref(shift);
  my ($message, %p)=@_;
  if (exists($p{Info}) && 1) {
    my $Info = $p{Info};
# 188 "PasswdFilesChecker.aas"
  my @list = splitList($Info);
  foreach $list( @list )
  {
	 delete $Params{MyRoots}{$list} ;
  }
  $self->Log('debug', "Removing entries from roots list \n");
    # By default, return undef
    return undef;
  }
}

sub command_DELETE_ALL {
  my $self=checkref(shift);
  my ($message, %p)=@_;
  if (1) {
    
# 281 "PasswdFilesChecker.aas"
	$Params{MyPasswFile} = {};
     $self->Log('debug', "Removing ALL files from password files list\n"); 

#=========================================================================
    # By default, return undef
    return undef;
  }
}

sub command_LIST_FILES {
  my $self=checkref(shift);
  my ($message, %p)=@_;
  if (1) {
    
# 247 "PasswdFilesChecker.aas"
  my $list ;
  $list = join ( ",", keys %{$Params{MyPasswFile}}) ;
  $self->Log('debug', "Listing the password files\n"); 
  return {Password_Files => $list } ;
    # By default, return undef
    return undef;
  }
}

sub command_FILES_RECORD {
  my $self=checkref(shift);
  my ($message, %p)=@_;
  if (exists($p{Info}) && 1) {
    my $Info = $p{Info};
# 254 "PasswdFilesChecker.aas"
  my @Name= splitList($Info) ;
  my $result ;

  foreach $name(@Name)
  {
    if ( defined ($Params{MyPasswFile}{$name}))
	{
	    $result.= "File name => $name;  Content = > $Params{MyPasswFile} ;";
	}
    else
    {
	$result.= "File name => $name; Content = > ;";
    }
  }  
  $self->Log('debug', "Showing data fields for password files\n"); 
  return { Password_Files_Values => $result };
    # By default, return undef
    return undef;
  }
}

sub command_ROOTS_LIST {
  my $self=checkref(shift);
  my ($message, %p)=@_;
  if (1) {
    
# 200 "PasswdFilesChecker.aas"
  my $list="";
  foreach $current( sort keys %{$Params{MyRoots}})
	{
	  $list.= $current.", ";
	}
  $self->Log('debug', "Providing a list with the approved roots \n"); 
 return { APPROVED_ROOT_USERS => $list };

#++++++++++++++++++++++++++++++++
    # By default, return undef
    return undef;
  }
}

sub command_ADD_SHELLS {
  my $self=checkref(shift);
  my ($message, %p)=@_;
  if (exists($p{Info}) && 1) {
    my $Info = $p{Info};
# 210 "PasswdFilesChecker.aas"
  my @list = splitList($Info);
  foreach $shell (@list)
	{ $Params{MyShells}{$shell} = 1;}
  $self->Log('debug', "Adding allowed shells\n");
    # By default, return undef
    return undef;
  }
}

sub command_SHELLS_DELETE_ALL {
  my $self=checkref(shift);
  my ($message, %p)=@_;
  if (1) {
    
# 224 "PasswdFilesChecker.aas"
	  $Params{MyShells} = {} ;
  $self->Log('debug', "Removing ALL entries from shells list \n");
    # By default, return undef
    return undef;
  }
}

sub command_LIST_WEIGHT_FIELDS {
  my $self=checkref(shift);
  my ($message, %p)=@_;
  if (1) {
    
# 174 "PasswdFilesChecker.aas"
  my $list = "";
  foreach $file (  keys %{$Params{MyWeights}}) 
		{ $list.= ":: $file => $Params{MyWeights}{$file} "; }
  $self->Log('debug', "Listing the weight fields\n"); 
  return {WEIGHT_FIELDS => $list } ;

#++++++++++++++++++++++++++++++++
    # By default, return undef
    return undef;
  }
}

sub command_SHELLS_DELETE {
  my $self=checkref(shift);
  my ($message, %p)=@_;
  if (exists($p{Info}) && 1) {
    my $Info = $p{Info};
# 216 "PasswdFilesChecker.aas"
  my @list = splitList($Info);
  foreach $list( @list )
  {
	 delete $Params{MyShells}{$list} ;
  }
  $self->Log('debug', "Removing entries from shells list \n");
    # By default, return undef
    return undef;
  }
}

sub command_ADD_ROOTS {
  my $self=checkref(shift);
  my ($message, %p)=@_;
  if (exists($p{Info}) && 1) {
    my $Info = $p{Info};
# 182 "PasswdFilesChecker.aas"
  my @list = splitList($Info);
  foreach $rootuser (@list)
	{  $Params{MyRoots}{$rootuser} = 1;}
  $self->Log('debug', "Adding root users\n");
    # By default, return undef
    return undef;
  }
}

# End of entity marker
_EndOfEntity;
