Unix::PasswdFileOps - Operations on Unix Passwd file


Unix-PasswdFileOps documentation Contained in the Unix-PasswdFileOps distribution.

Index


Code Index:

NAME

Top

Unix::PasswdFileOps - Operations on Unix Passwd file

SYNOPSIS

Top

  use Unix::PasswdFileOps;

  my $pass = Unix::PasswdFileOps->new('passwd' => '/etc/passwd');
  print $pass->passwd();
  $pass->verbose(1);
  $pass->protect_zero(1);
  if($pass->sort_passwd())
  {
     print $pass->error;
  }

DESCRIPTION

Top

This module will perform sorting on a standard UNIX passwd file, the sort is performed against the UID by default although this can be altered using the sort_field() function.

Additionally it can populate an internal hash of arrays with line information this provides a nice interface to find information about user accounts.

FUNCTIONS

Top

new

my $passwd = Unix::PasswdFileOps->new('passwd' => '/etc/passwd');

You can pass in the optional parameters 'passwd', 'protect_zero' 'verbose' and 'sort_field'

passwd

my $passwd_file = $pass->passwd(); # or $pass->passwd('/etc/passwd');

This function will allow you to view or set the passwd file parameter, if you pass a parameter it will set the passwd file to that parameter, if you do not it will just return the currently set file.

protect_zero

my $zero = $pass->protect_zero(); # or $pass->protect_zero(1);

This function will allow you to view or set the protect_zero parameter, if you pass a parameter it will set the protect_zero option to 1, if you do not it will just return the currently set parameter.

If the protect_zero option is set all 0 uids will be unsorted and left at the top of the file, this is useful if you have more than one user with UID 0.

unprotect_zero

my $zero = $pass-unprotect_zero(); # or $pass->unprotect_zero(1);

This function will allow you to view or unset the protect_zero parameter, if you pass a parameter it will set the protect_zero option to undef, if you do not it will just return the currently set parameter.

If the protect_zero option is set all 0 uids will be unsorted and left at the top of the file, this is useful if you have more than one user with UID 0.

verbose

my $verbose = $pass->verbose(); # or $pass->verbose(1);

This function will allow you to view or set the verbose parameter, if you pass a parameter it will set the verbose option to that parameter, if you do not it will just return the currently set parameter.

This is only useful during the passwd_sort function output will be printed to screen if this is enabled

sort_field

my $sort_field = $pass->sort_field(); # or $pass->sort_field(1);

This function will allow you to view or set the sort_field parameter, if you pass a parameter it will set the sort_field option to that parameter, if you do not it will just return the currently set parameter.

The sort_field option determines which field to sort the passwd file by, the default is field 2 the UID field.

error

my $err = $pass->error();

This function will allow you to view any error messages

sort_passwd

my $zero = $pass->sort_passwd(); # or $pass->sort_passwd();

This function performs a sort on the current passwd file, technically this is a safe process the sort type is determined by the sort_field option or the default field 2 (array element 2) this has been tested on Linux, Solaris 8, and almost 200 System V R 4.3 machines. It should be safe on any standard unix passwd file.

The file is read into the function and the sorted output is written back to the file, it is suggested that you create a backup of the passwd file before running this function.

populate_stats

$pass->populate_stats();

This function will populate an internal hash of arrays with the contents of the passwd file. You can access these using the following:

$pass->{'file_stats'}->{'username'}->{'list'}[0];

You can substitute 'username' with 'uid', 'gid', 'fullname', 'homedir', and 'shell'.

SEE ALSO

Top

man passwd

AUTHOR

Top

Ben Maynard, <cpan@geekserv.com> <http://www.benmaynard.com>

COPYRIGHT AND LICENSE

Top


Unix-PasswdFileOps documentation Contained in the Unix-PasswdFileOps distribution.
package Unix::PasswdFileOps;

use 5.008007;
use strict;
use warnings;
use Carp;
use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);

require Exporter;

@ISA = qw(Exporter);
@EXPORT_OK = qw/new validate identify barcode type/;
@EXPORT      = qw//;
%EXPORT_TAGS = (all => [@EXPORT_OK]);
$VERSION     = "0.4";

# Preloaded methods go here.

sub new {
	my $class  = "Unix::PasswdFileOps";
	my %params = @_;
	my $self   = {};
	$self->{'passwd'}       = $params{'passwd'}       || undef;
	$self->{'protect_zero'} = $params{'protect_zero'} || undef;
	$self->{'verbose'}      = $params{'verbose'}      || undef;
	$self->{'sort_field'}   = $params{'sort_field'}   || undef;
	bless $self, $class;
	return $self;
}

###
# Internal function
#

sub _error_msg {
   my $self = shift;
   $self->{'error'} = shift;
}

sub passwd {
	my ($self, $new_val) = @_;
	$self->{'passwd'} = $new_val if $new_val;
	return $self->{'passwd'};
}

sub protect_zero {
	my ($self, $new_val) = @_;
	$self->{'protect_zero'} = 1 if $new_val;
	return $self->{'protect_zero'};
}

sub unprotect_zero {
	my ($self, $new_val) = @_;
	$self->{'protect_zero'} = undef if $new_val;
	return $self->{'protect_zero'};
}

sub verbose {
	my ($self, $new_val) = @_;
	$self->{'verbose'} = $new_val if $new_val;
	return $self->{'verbose'};
}

sub sort_field {
	my ($self, $new_val) = @_;
	if (($new_val) && ($new_val >= 0) && ($new_val <= 6)) {
		$self->{'sort_field'} = $new_val;
	}
	else {
		_error_msg($self, "$new_val not within 0 - 6 range");
		return 1;
	}
	return $self->{'sort_field'};
}

sub error {
	my $self = shift;
	return $self->{'error'};
}

sub sort_passwd {
	my $self         = shift;
	my %sort_lines   = ();
	my @unsort_lines = ();
	my $sort_field   = shift;

        if (($self->{'sort_field'}) && ($self->{'sort_field'} <= 0) && ($self->{'sort_field'} >= 6)) {
		_error_msg($self, $self->{'sort_field'}." not within 0 - 6 range");
		return 1;    
	}
        elsif (($self->{'sort_field'}) && ($self->{'sort_field'} >= 0) && ($self->{'sort_field'} <= 6))	{
       		$sort_field = $self->{'sort_field'};
	}
	else {
		$sort_field = 2;
	}

	defined($self->{'passwd'}) ? my $passwd = $self->{'passwd'} : return 1;
  
	open(PWD,"$passwd") || _error_msg($self, "Cannot open $passwd: $!") && return 1; 
	{
		while(<PWD>) {
			chomp();
			my $line = $_;
			my @lines = split(":", $_, 6);
            
			if (($lines[2] == 0) && ($self->{'protect_zero'})) {
				print "Not sorting: $line" if $self->{'verbose'};
				push(@unsort_lines, $line);
			}
			else {
				if ( $sort_lines{$lines[$sort_field]} ) {
					$sort_lines{$lines[$sort_field]} .= "\n".$line;
				}
				else {
					$sort_lines{$lines[$sort_field]} = $line;
				}
			}
		}
	}
	close(PWD);

	open(PASS2, ">$passwd") || _error_msg($self, "Cannot open $passwd: $!") && return 1; ;
	{
		foreach my $key (@unsort_lines) {
			print PASS2 "$key\n";
		}

        	if ($sort_field !~ /[23]/) {
			foreach my $key (sort { $a cmp $b } keys %sort_lines) {
				print $sort_lines{$key}."\n" if $self->{'verbose'};
				print PASS2 $sort_lines{$key}."\n";
			}
        	}
		else {
			foreach my $key (sort { $a <=> $b } keys %sort_lines) {
				print $sort_lines{$key}."\n" if $self->{'verbose'};
				print PASS2 $sort_lines{$key}."\n";
			}
		}
	}
	close(PASS2);

    return 0;
}

sub populate_stats {
	my $self = shift;

	defined($self->{'passwd'}) ? my $passwd = $self->{'passwd'} : return 1;
  
	open(PWD,"$passwd") || _error_msg($self, "Cannot open $passwd: $!") && return 1; 

	while(<PWD>) {
		chomp;
		my @lines = split(/:/, $_);

		push(@{ $self->{'file_stats'}->{'username'}->{'list'} }, $lines[0]);
  		push(@{ $self->{'file_stats'}->{'uid'}->{'list'} },      $lines[2]);
		push(@{ $self->{'file_stats'}->{'gid'}->{'list'} },      $lines[3]);
		push(@{ $self->{'file_stats'}->{'fullname'}->{'list'} }, $lines[4]);
		push(@{ $self->{'file_stats'}->{'homedir'}->{'list'} },  $lines[5]);
		push(@{ $self->{'file_stats'}->{'shell'}->{'list'} },    $lines[6]);
	}

	close(PWD);
}

1;
__END__