Paranoid

 view release on metacpan or  search on metacpan

CHANGELOG  view on Meta::CPAN

==================
--Typos in documentation (Debian Perl Group)
--Fixed bug in pflock in Paranoid::Process that failed to apply the 
  flock as requested
--Improved pflock testing as used by Paranoid::Log::File
--Updated Paranoid::IO::Line POD to clarify the third option to many
  functions which control line chomping.
--Improved Paranoid::Process to constrain SIGCHLD handling to only those 
  children forked specifically with/pfork().  This keeps evals and
  miscellaneous system calls from skewing the counter.
--Fixed pchown tests for platforms that use negative numbers for uid/gid

v2.05 (2017/03/23)
==================
--pkmdir would fail when given paths that included . or .. subdirs,
  fixed
--improved error message from pkmdir to make it obvious what specific
  portion of the path failed
--fixed a bug in popen where reopening a filehandle that was stored 
  under its absolute name deleted the internal cache record
--fixed sigchld signal preemption so it doesn't miss children exit

CHANGELOG  view on Meta::CPAN

--Removed excessive external locking in Paranoid::BerkeleyDB -- hopefully
  internal CDB locking mechanism is robust enough
--Made user input validation on Paranoid::Filesystem non-fatal (handing in
  undefs as filenames, etc.)
--Removed MAXLINKS in Paranoid::Filesystem


v0.23  (2009/03/17)
===================
--Fixed tests that weren't fully supported on all platforms
--Commented out pchown tests which were failing to due to a bug
  in Perl.  A patch has been submitted to bleadperl to address it.
--Added manual detaint of TERM environment variable in psecureEnv
--Updated documentation to include Paranoid::Data
--Made getKeys in Paranoid::BerkeleyDB use finer grained locking
--Added Paranoid::Data
--Added sip, tail, and closeFile functions
--Fixed bug in preadDir that added undef records while filtering out
  symlinks (bug introduced in v0.21)

v0.21  (2009/03/04)
===================
--Massive reformat with Perl::Tidy
--Massive rewrite to accommodate Perl::Critic
--Converted all tests to use Test::More
--Converted licensing to be same as Perl
--Documentation updates
--Updated to only support Perl 5.6 or better
--Fixed bug in pcapture to return appropriate return values
--Fixed bug in pchmodR/pchownR to return correct RV (false)
  with non-existant targets
--Added Paranoid::Args

v0.20  (2008/04/28)
===================
--Misc. POD updates

Paranoid::Filesystem:
--Fixed bug in the recursion wrapper where there were errors in certain
  modes when called on a hierarchy that included an empty subdirectory

MANIFEST  view on Meta::CPAN

t/10_io_line.t
t/11_args.t
t/12_lockfile-lockstack.t
t/12_lockfile.t
t/20_filesystem_pmkdir.t
t/21_filesystem_preadDir.t
t/22_filesystem_prm.t
t/23_filesystem_ptouch.t
t/24_filesystem_misc.t
t/25_filesystem_pchmod.t
t/26_filesystem_pchown.t
t/30_log.t
t/31_log_buffer.t
t/32_log_file-lockstat.t
t/32_log_file.t
t/33_log_pdebug.t
t/40_socket.t
t/41_ipv4.t
t/42_ipv6.t
t/43_network.t
t/50_process.t

lib/Paranoid.pm  view on Meta::CPAN

#BEGIN {
#die "This module requires taint mode to be enabled!\n" unless
#  ${^TAINT} == 1;
#delete @ENV{qw(IFS CDPATH ENV BASH_ENV)};
#$ENV{PATH} = '/bin:/sbin:/usr/bin:/usr/sbin';
#no ops qw(backtick system exec);
#  :subprocess = system, backtick, exec, fork, glob
#  :dangerous = syscall, dump, chroot
#  :others = mostly IPC stuff
#  :filesys_write = link, unlink, rename, mkdir, rmdir, chmod,
#                   chown, fcntl
#  :sys_db = getpwnet, etc.
#}

sub psecureEnv (;$) {

    # Purpose:  To delete taint-unsafe environment variables and to sanitize
    #           the PATH variable
    # Returns:  True (1) -- no matter what
    # Usage:    psecureEnv();

lib/Paranoid.pm  view on Meta::CPAN

passed for boolean true use-cases.

=head1 TAINT NOTES

Taint-mode programming can be somewhat of an adventure until you know all the
places considered dangerous under perl's taint mode.  The following functions
should generally have their arguments detainted before using:

  exec        system      open        glob
  unlink      mkdir       chdir       rmdir
  chown       chmod       umask       utime
  link        symlink     kill        eval
  truncate    ioctl       fcntl       chroot
  setpgrp     setpriority syscall     socket
  socketpair  bind        connect

=head1 DEPENDENCIES

While this module itself doesn't have any external dependencies various child
modules do.  Please check their documentation for any particulars should you
use them.

lib/Paranoid/Filesystem.pm  view on Meta::CPAN

use Paranoid::Process qw(ptranslateUser ptranslateGroup);
use Paranoid::Input;
use Paranoid::IO;
use Paranoid::Glob;

($VERSION) = ( q$Revision: 2.10 $ =~ /(\d+(?:\.\d+)+)/sm );

@EXPORT = qw(
    preadDir     psubdirs    pfiles
    pmkdir       prm         prmR      ptouch
    ptouchR      pchmod      pchmodR   pchown
    pchownR      pwhich
    );
@EXPORT_OK = (
    @EXPORT, qw(
        ptranslateLink
        pcleanPath
        ptranslatePerms
        ) );
%EXPORT_TAGS = ( all => [@EXPORT_OK], );

use constant PERMMASK => 0777;

lib/Paranoid/Filesystem.pm  view on Meta::CPAN

        # Load the directory tree and execute pchmod
        $rv = $glob->recurse( $follow, 1 )
            && pchmod( $glob, $perms, %$errRef );
    }

    subPostamble( PDLEVEL1, '$', $rv );

    return $rv;
}

sub pchown ($$;$\%) {

    # Purpose:  Simulates a "chown" command in pure Perl
    # Returns:  True (1) if all targets were successfully owned,
    #           False (0) if there are any errors
    # Usage:    $rv = pchown("/foo", $user);
    # Usage:    $rv = pchown("/foo", $user, $group);
    # Usage:    $rv = pchown("/foo", $user, $group, %errors);

    my $target = shift;
    my $user   = shift;
    my $group  = shift;
    my $errRef = shift;
    my $rv     = 1;
    my ( $glob, $tglob, @fstat );

    subPreamble( PDLEVEL1, '$$;$\%', $target, $user, $group, $errRef );

lib/Paranoid/Filesystem.pm  view on Meta::CPAN

        pdebug( 'UID: %s GID: %s', PDLEVEL2, $user, $group );

        # Consolidate the entries
        $glob->consolidate;

        # Process the list
        foreach (@$glob) {

            pdebug( 'processing %s', PDLEVEL2, $_ );

            unless ( chown $user, $group, $_ ) {
                $rv = 0;
                $$errRef{$_} = $!;
                Paranoid::ERROR =
                    pdebug( 'failed to adjust ownership of %s: %s',
                    PDLEVEL1, $_, $! );
            }
        }
    }

    subPostamble( PDLEVEL1, '$', $rv );

    return $rv;
}

sub pchownR ($$;$$\%) {

    # Purpose:  Calls pchown recursively
    # Returns:  True (1) if all targets were successfully owned,
    #           False (0) if there are any errors
    # Usage:    $rv = pchownR("/foo", $user);
    # Usage:    $rv = pchownR("/foo", $user, $group);
    # Usage:    $rv = pchownR("/foo", $user, $group, $follow);
    # Usage:    $rv = pchownR("/foo", $user, $group, $follow, %errors);

    my $target = shift;
    my $user   = shift;
    my $group  = shift;
    my $follow = shift;
    my $errRef = shift;
    my $rv     = 1;
    my ( $glob, $tglob );

    subPreamble( PDLEVEL1, '$$;$$\%', $target, $user, $group, $follow,

lib/Paranoid/Filesystem.pm  view on Meta::CPAN

    if ( defined $target ) {
        $glob =
            ref $target eq 'Paranoid::Glob'
            ? $target
            : Paranoid::Glob->new( globs => [$target] );
    }
    $rv = 0 unless defined $glob;

    if ($rv) {

        # Load the directory tree and execute pchown
        $rv = $glob->recurse( $follow, 1 )
            && pchown( $glob, $user, $group, %$errRef );
    }

    subPostamble( PDLEVEL1, '$', $rv );

    return $rv;
}

sub pwhich ($) {

    # Purpose:  Simulates a "which" command in pure Perl

lib/Paranoid/Filesystem.pm  view on Meta::CPAN

  $rv = pmkdir("/foo/{a1,b2}");

  $rv = preadDir("/tmp", @entries);
  $rv = psubdirs("/etc", @dirList);
  $rv = pfiles("/etc", @filesList);

  $rv = ptouch("/foo/*", $tstamp);
  $rv = ptouchR("/foo", $tstamp, $follow, %errors);
  $rv = pchmod("/foo", $perms);
  $rv = pchmodR("/foo", $perms, $follow, %errors);
  $rv = pchown("/foo", $user, $group);
  $rv = pchownR("/foo", $user, $group, $follow, %errors);

  $rv = prm("/foo");
  $rv = prmR("/foo", 1, %errors);

  $fullname = pwhich('ls');
  $cleaned  = pcleanPath($filename);
  $noLinks  = ptranslateLink("/etc/foo/bar.conf");
  $rv       = ptranslatePerms("ug+rwx");

  $filename = pwhich('ls');

lib/Paranoid/Filesystem.pm  view on Meta::CPAN

tracing into each function you must set B<PDEBUG> to at least 9.

B<pcleanPath>, B<ptranslateLink>, and B<ptranslatePerms> are only exported 
if this module is used with the B<:all> target.

=head1 IMPORT LISTS

This module exports the following symbols by default:

    preadDir psubdirs pfiles pmkdir prm prmR ptouch
    ptouchR pchmod pchmodR pchown pchownR pwhich

The following specialized import lists also exist:

    List        Members
    --------------------------------------------------------
    all         @defaults ptranslateLink pcleanPath 
                ptranslatePerms

=head1 SUBROUTINES/METHODS

lib/Paranoid/Filesystem.pm  view on Meta::CPAN

=head2 pchmodR

  $rv = pchmodR("/foo", $perms);
  $rv = pchmodR("/foo", $perms, $follow);
  $rv = pchmodR("/foo", $perms, $follow, %errors);

This function works the same as B<pchmod>, but offers one additional
argument (the third argument), boolean, which indicates whether or not the
command should follow symlinks.

=head2 pchown

  $rv = pchown("/foo", $user);
  $rv = pchown("/foo", $user, $group);
  $rv = pchown("/foo", $user, $group, %errors);

This function takes a user and/or a named group or ID and applies it to
every file given to it.  If either the user or group is undefined it leaves
that portion of ownership unchanged.

File arguments are processed through L<Paranoid::Glob> and expanded into 
multiple targets if globs are detected, or you can hand it a populated glob
object directly.

The error message from each failed operation will be placed into the passed
hash using the filename as the key.

The return value will be true unless any errors occur during the actual
chown operation including attempting to set permissions on non-existent
files.  

=head2 pchownR

  $rv = pchownR("/foo", $user);
  $rv = pchownR("/foo", $user, $group);
  $rv = pchownR("/foo", $user, $group, $follow);
  $rv = pchownR("/foo", $user, $group, $follow, %errors);

This function works the same as B<pchown>, but requires one additional
argument (the fourth argument), boolean, which indicates whether or not the
command should follow symlinks.

=head2 pwhich

  $fullname = pwhich('ls');

This function tests each directory in your path for a binary that's both
readable and executable by the effective user.  It will return only one
match, stopping the search on the first match.  If no matches are found it

t/26_filesystem_pchown.t  view on Meta::CPAN

    open $fh, '>', $filename or die "Couldn't touch file $filename: $!\n";
    while ( $size - 80 > 0 ) {
        print $fh 'A' x 79, "\n";
        $size -= 80;
    }
    print $fh 'A' x $size;
    close $fh;
}

my ( $user, $group, $uid, $gid, $id, %errors );
mkdir './t/test_chown';
mkdir './t/test_chown2';
mkdir './t/test_chown2/foo';
symlink '../../test_chown', './t/test_chown2/foo/bar';
touch('./t/test_chown/foo');
touch('./t/test_chown/bar');

$user  = 'nobody';
$uid   = ptranslateUser($user);
$group = 'nobody';
$gid   = ptranslateGroup($group);
my $hasNG = defined $gid;

# NOTE: The following block is skipped due to a bug in all current
# version of Perl involving platforms with unsigned ints for GIDs.  A patch
# has been submitted to bleadperl to fix it.
SKIP: {
    skip( 'Bug in some perls UINT in GIDs', 15 ) unless $] >= 5.010;
    skip( 'Non-root user running tests',    15 ) unless $< == 0;
    skip( 'Failed to resolve nobody/nobody to test with', 15 )
        unless defined $uid and defined $gid;
    ok( pchown( "./t/test_chown/*", $user ), 'pchown no group 1' );
    $id = ( stat "./t/test_chown/foo" )[4];
    is( $id, $uid, 'pchown no group 2' );
    ok( pchown( "./t/test_chown/*", undef, $group ), 'pchown no user 1' );
    $id = ( stat "./t/test_chown/foo" )[5];
    is( $id, $gid, 'pchown no user 2' );
    ok( pchown( "./t/test_chown/*", 0, 0, %errors ), 'pchown both 1' );
    ok( pchownR( "./t/test_chown2", $user ), 'pchownR no group/no follow 1' );
    $id = ( stat "./t/test_chown2/foo" )[4];
    is( $id, $uid, 'pchownR no group/no follow 2' );
    $id = ( stat "./t/test_chown/foo" )[4];
    is( $id, 0, 'pchownR no group/no follow 3' );
    ok( pchown( "./t/test_chown/*", 0, 0 ), 'pchown both 2' );
    ok( pchownR( "./t/test_chown2", -1, $group, 1, %errors ),
        'pchownR no user/follow 1' );
    $id = ( stat "./t/test_chown2/foo" )[5];
    is( $id, $gid, 'pchownR no user/follow 2' );
    $id = ( stat "./t/test_chown/foo" )[5];
    is( $id, $gid, 'pchownR no user/follow 3' );
    $id = ( stat "./t/test_chown/foo" )[4];
    is( $id, 0, 'pchownR no user/follow 4' );
    ok( !pchown( "./t/test_chown2/roo", -1, $group, %errors ),
        'pchown no user 2' );
    ok( !pchownR( "./t/test_chown2/roo", -1, $group, 1, %errors ),
        'pchownR no user/follow 5' );
}

system('rm -rf ./t/test_chown* 2>/dev/null');



( run in 1.607 second using v1.01-cache-2.11-cpan-71847e10f99 )