Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"
 
PerlMonks  

Let the staff back in!

by Intrepid (Deacon)
on Aug 01, 2003 at 09:45 UTC ( [id://279905]=sourcecode: print w/replies, xml ) Need Help??
Category: Utility Scripts
Author/Contact Info Soren Andersen <somian -AT- pobox *DOT* com>
Description:

rectify-perms-perl-sitedirs

A *NIX Perl installation administration / maintainance utility.

This script is a specific instance of the "recurse and fix permissions / file ownership" -type that has been written (doubtless) many times over by *nix system admins around the globe. As such it isn't very special but might still be particularly welcomed by newbies and those not used to quickly writing scripts for such admin tasks.

Please do not attempt to read this explanation if you already have started to get a headache or tend to get them. It will most likely make it worse. ;-)

The Background, Introduction

General confusion, lack of experience and an understandable frustration with one aspect of how the CPAN.pm tool works led the author to make an operator error which left his Perl installation in an incorrect and problematic condition. That condition and the circumstances which led to it are described below. It is the author's belief that this scenario will not be uncommon and thus the script might be useful to more people than he anticipates.

There are specific Circumstances

Only users with some administrative role on their systems should be needing to use or considering using this program. Others will not be able to run it as root, which is necessary to its function (which is to change ownership and permissions modes on files found in the Perl sitearch and sitelib directories). If these specific circumstances apply to the reader, please read on.

The author's system is running Debian GNU/Linux. The Perl package for this OS distribution is governed by, compliant with, made according to Debian packaging policy. That policy states that software not under package manager (dpkg) control should go into the /usr/local filesystem area (as opposed to any part under /usr). The perms for the /usr/local tree are supposed to allow the group named staff to have rw permissions on that whole tree, including the perl site directories (where CPAN-downloaded modules are to be installed). Although this is somewhat lengthy to explain, the intention of doing so is to point out that not every system is administered under policies similar to this one, the author of this code cannot know what proper system policies are on the user's system, and any use of the program presented here and any consequences thereof are entirely at the user's risk. The author assumes no responsibility whatsoever for the performance of the program, consequences either direct or indirect resulting from its use, of accuracy or correctness of any information presented by him here in connection to this program.

More Background Description

When installing modules using CPAN.pm the specific module installation is subject to certain rules or parameters dictated by the author of the module in accordance with what category the module falls into. A module that is part of core Perl for a particular Perl release (and those that come after, in most cases) needs to be installed into the core perl area ($Config::Config{privlib} or $Config::Config{archlib}, instead of in $Config::Config{site(arch|lib)}. The parameter flags in the Makefile.PL file determine where the module is to be put at installation time, but these can be overidden by the user. The default (in absence of any flags or user overrides) is to put all modules under $Config::Config{site(arch|lib)}.

When choosing modules to install using CPAN.pm, the author has not always been aware of whether the modules were destined for core perl locations or the usual non-core locations. Lacking this knowledge beforehand results in installation failure while the CPAN process is running, after all make and make test parts have completed. This is annoying and frustrating behavior from the tool, and drives a former MS Windows user, still getting used to the (blessedly) stricter world of *nix security norms, a little crazy. The naive measures the author took following this sort of incident was to restart the CPAN program as root and finish installing whatever modules he wanted on that occasion. The result of this is that module files were installed to the site perl locations with root ownership and permissions resulting from umask 022 (a standard setting), which yield files and directories unwriteable by the staff group members. The next time those modules need to be upgraded by user belonging to staff, the operations required are going to be impossible because the perms act restrictively to prevent them.

This kind of clumsy and inexpert *nix administration is most likely to happen when a self-trained user like myself who is lacking years of experience and formal training has insufficiently grasped the principles of *nix security. That's granted. However the author got there, though, he had to get himself out. Instead of continuing to run CPAN as root and thereby perpetuate the problem, running the program presented here allowed the repair of those directories and files perms so that in the future he could run the CPAN as a user belonging to staff, but not as the superuser, as is supposed to be done (and strongly recommended on general principle).

This may have seemed more of a Meditation than a Catacomb description, but the author felt it important to explain clearly in what circumstances this tool might be useful and why it is as specific as it is. A more general-purpose tool for accomplishing the same category of adminisrative tasks was written by Tye and placed in the Code Catacombs some time ago, and is recommended highly. The only reason for using my program in preference to that one is: that the tool Tye wrote is so powerful in its general-purpose nature that it could do serious damage in the event of unknowledgeable user error. So without further ado, the code ...

The Code

The `find2perl' program included in perl 5.6.1 was used to generate a starting framework for this program. The author credits the writers of find2perl for their contribution and in no way takes credit for it. The author must also thank some Perl Monks, especially merlyn and Tye, for their help with working out the details of bitwise operations and octal representation of *nix permissions.

#! /usr/bin/env perl
# "rectify-perms-perl-sitedirs" - does about what it's called.
# (C) 2003 Soren Andersen, All Rights Reserved. This software
# may be modified or redistributed under the same terms as Perl
# itself. Free Software. Absolutely no warrantee.

# Version 03.08.01

use strict;
use warnings;
use Config;
use File::Find ();
use Cwd ();
# Tell me the known group with access rights "+w" to the Perl site loc
+ation:
my $STAFF = 'staff';  # Adjust for your os.

# for the convenience of &wanted calls, including -eval statements:
use vars qw/*name *dir *prune/;
*name   = *File::Find::name;
*dir    = *File::Find::dir;
*prune  = *File::Find::prune;
my (%gid, %group);
my $cwd = Cwd::cwd();
while (my ($name, $pw, $gid) = getgrent) {
    $gid{$name} = $gid{$gid} = $gid;
}

my @Searchin;
for my $thistop ($Config::Config{sitearchexp} , $Config::Config{siteli
+bexp}) {
    push @Searchin , $thistop unless do {
      my $other = $thistop eq $Config::Config{sitelibexp} ?
                     $Config::Config{sitearchexp} : $Config::Config{si
+telibexp};
      $other =~/^$thistop\w+/;          };
}

# Traverse site(arch|lib)exp filesystems, fix perms when wrong.
File::Find::find({wanted => \&wanted}, @Searchin);
exit;

sub Can_Chgrp  {
    return 1;  # TODO
}

sub wanted {
    my ($dev,$ino,$mode,$nlink,$uid,$gid);

    unless (($dev,$ino,$mode,$nlink,$uid,$gid) = lstat($_)) {
        die "Could not lstat() \"$_\", terminating!\n";
    }

    unless ($gid == $gid{$STAFF}) {
         &doexec(1, 'chgrp', '-c', $STAFF, '{}') if &Can_Chgrp();
    }

    if ( -d _ && ($gid == $gid{$STAFF}) &&
    ! (($mode & 0660) == 0660) )
    {
         &doexec(1, 'chmod','-c','ug+w','{}');
    }
}

sub doexec {
    my $ok = shift;
    my $confit;
    my @pargs = @_;
    for my $word (@pargs)
    {
        ($word =~s#{}#$name#g) &&
    ($confit = $word);
    }
    if ($ok) {
        my $old = select(STDOUT);
        $| = 1;
        print "Do this: " ,join(" ",@pargs), " ? ";
        select($old);
        return 0 unless <STDIN> =~ /^y/i;
    }
    chdir $cwd; #sigh
    system @pargs;
    chdir $File::Find::dir;
    return !$?;
}


__END__

On Debian GNU/Linux "woody", Perl release 5.6.1 has these build-time d
+irectory params:

archlib='/usr/lib/perl/5.6.1'
archlibexp='/usr/lib/perl/5.6.1'
privlib='/usr/share/perl/5.6.1'
privlibexp='/usr/share/perl/5.6.1'

bin='/usr/bin'
binexp='/usr/bin'
sitebin='/usr/local/bin'
sitebinexp='/usr/local/bin'

sitearch='/usr/local/lib/perl/5.6.1'
sitearchexp='/usr/local/lib/perl/5.6.1'
sitelib='/usr/local/share/perl/5.6.1'
sitelibexp='/usr/local/share/perl/5.6.1'

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: sourcecode [id://279905]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others perusing the Monastery: (6)
As of 2024-04-19 10:17 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found