Update of /cvsroot/hcoop/misc/scripts
In directory sc8-pr-cvs17.sourceforge.net:/tmp/cvs-serv31942

Added Files:
        freeze frozen_shell 
Log Message:

* Commit frozen_shell
* Commit working freeze script



--- NEW FILE: frozen_shell ---
#!/bin/sh

echo "

Please pay your HCoop dues to have your access restored.

All information on making a payment is available on our Members Portal,

  https://members.hcoop.net/

Contact HCoop system administrators at [EMAIL PROTECTED] if you
cannot access the Portal.

Thank you,
HCoop

";

exit 0;


--- NEW FILE: freeze ---
#!/usr/bin/perl

#
# Purpose: freeze user (cancel user services except email), or unfreeze user.
#
# Usage (RUN AS _ADMIN USER ON DELEUZE WITHOUT SUDO):
#
# Display frozen users or details for one user (one user implies -verbose):
#   freeze  [user], OR
#   freeze [ --action list | -a ] [--verbose | -v] [user]
#
# Freeze user:
#   freeze -a f user
#
# Unfreeze:
#   freeze -a u user
# 
#
# How it works:
#
# Script invokes a list of modules, where each module knows how to
# implement and unimplement a specific restriction. Implemented modules
# should be listed in @modules array or they won't get called. Admin
# can override list of modules with --modules=one,two,three.
#
# Modules execute in the order as specified for freeze, and in reverse
# order for unfreeze.
#
# Module gets called as  &module($action, $user)  . The proper way to 
# test for which action is requested is as shown below. (Note that
# module adds or removes itself to the list of modules that ran on the user).
#
# if ($a =~ /^f/i) {
#   ... freeze ...
#   push @{ $$store{$u}{modules} }, 'MODULE';
# } elsif ($a =~ /^u/i) {
#   ... unfreeze ...
#   @{ $$store{$u}{modules} } = grep {!/^MODULE$/} @{ $$store{$u}{modules} };
# }
#
# Also each system-modifying action should be wrapped in if (!DRY) as shown:
#
#    if (!DRY) {
#      system(qq{SOME COMMAND})
#    } else {
#      warn qq|SOME COMMAND|
#    }
#
# User is valid system username, and user's getent entry is prepared and
# retrievable through @user array, should you need some of its info.
#
# Module can save all persistent data to $$store{$user}{$modulename}. For 
# example, after cron module removes user from all cron.allows, it
# registers the machines where user was removed to 
# @{ $$store{$u}{cron} }, so that it can revert it back if user is
# unfreezed.
#
# Module 'record' creates or deletes initial user entry in $$store.
# If you create a new module that will use the store, announce its
# hash key by creating it empty in record().
#
# For additional detail, here's how the stored hash might look like:
#
#
# $store = {
#    user1 => {
#      date => 'Sun Jun 29 18:45:43 CEST 2008',
#      getent => [qw/docelic 1000 1000 DavorOcelic /home/docelic /bin/bash]
#
#      modules => [qw/login domtool cron slay/],         # (modules that ran)
#      domains => [qw/spinlock.hr test.hr/],    # (domains that were removed)
#      cron => [qw/mire/],       # (hosts where cron.allow entry was removed)
#    },
#    user2 => {
#           ...
#    },
#   ...
#   ...
#   ...
# }
#
#
# Wiki page relating to this script is http://wiki.hcoop.net/MemberFreezing
#
# Davor Ocelic, [EMAIL PROTECTED], Sun Jun 29 18:41:02 CEST 2008
#
#

use warnings;
use strict;

use Storable qw/lock_nstore lock_retrieve/;
use Getopt::Long qw/GetOptions/;

use constant DEBUG => 1;
use constant DRY => 0;
use constant STORE => "/var/tmp/frozen/cache";
use constant DEFAULT_SHELL => '/bin/bash';
use constant FROZEN_SHELL => '/afs/hcoop.net/common/etc/scripts/frozen_shell';
use constant PUBLIC_ACCESS => (qw/mire/);
use constant RUN_SERVER => 'deleuze';

my $store = {}; # cached info
my $action = 'list'; # list, freeze, unfreeze
my $verbose = 0; # 0/1 (print which modules were applied to user in freezing)
my $force = 0; # 0/1 (force action even if user already freezed/unfreezed)
my $user; # who to freeze/unfreeze
my @user; # getent passwd entry for user
my $modules; # list of freeze/unfreeze actions to take
my @modules; # modules, possibly overriden by split /,\s+/, $modules

# Keep modules listed in order of application, honoring possible dependencies.
@modules = (qw/record login domtool slay/);

unless ( GetOptions (
        'do|d|a=s'     => \$action,
        'verbose|v!'   => \$verbose,
        'force!'       => \$force,
        'modules|m=s'  => \$modules,
)) { die "Error parsing options: $!\n" }

$user = shift ;

if ( $> == 0 or $< == 0 ) {
        die "Run script under admin account without sudo.\n";
}

if ( -e STORE ) {
        $store = lock_retrieve(STORE);
} else {
        warn "No '" . STORE . "', skipping load.\n";
}

if ( `hostname` ne RUN_SERVER . "\n" ) {
        die "Please run script on " . RUN_SERVER . "\n";
}

if ( $action =~ /^l/i ) {
        while (my ($k,$v) = each %$store ) {
                if (! $user or $user eq $k ) {
                        print "$k          $$v{date}\n";
                        print "  @{$$v{modules}}\n" if $verbose or $user;
                }
        }
        exit 0;
}

$user or die "Must specify user to freeze/unfreeze. Exiting.\n";
$user =~ /^[a-z0-9]+$/ or die "Invalid username (not [a-z0-9]+).\n";
@user = split(/:/, `getent passwd $user`);
@user or die "No such user? (getent passwd USER empty.)\n";
chomp $user[$#user];

if ( $action !~ /^[fu]/i ) {
        warn "Unknown action: use -a [list (l)|freeze (f)|unfreeze (u)]\n";
}

if ( $action =~ /^f/i ) {
        if ( exists $$store{$user} ) {
                warn "User already frozen since $$store{$user}{date}.\n";
                if (! $force) {
                        die "Exiting.\n";
                }
        }
}

elsif ( $action =~ /^u/i ) {
        if (! exists $$store{$user} ) {
                warn "User not frozen in the first place.\n";
                if (! $force) {
                        die "Exiting.\n";
                }
        }
}

else {
        warn "How did you get through?\n";
        die;
}


if ($modules) { @modules = split /[,\s+]/, $modules; }
for ( $action =~ /^u/i ? reverse @modules : @modules ) {
        no strict 'refs';
        print "Module: $_\n";
        &{ $_ }($action, $user);
}

lock_nstore $store, STORE;


###########################################################################
# Helpers below

# GETENT (available to modules automatically in @user):
#    0    1   2    3      4                    5                     6
# docelic:x:10235:65534:docelic:/afs/hcoop.net/user/d/do/docelic:/bin/bash

sub record {
        my ($a, $u) = @_;
        $a =~ /^f/i and $$store{$u} = {
                date => scalar localtime,
                getent => [ @user ],
                modules => [],
                domains => [],
                cron => [],
        };
        $a =~ /^u/i and delete $$store{$u};
}

sub login {
        my ($a, $u) = @_;

        if ($a =~ /^f/i) {
                if ( $user[6] ne DEFAULT_SHELL ) {
                        $$store{$u}{shell} = $user[6] unless $user[6] eq 
FROZEN_SHELL;
                }


                if ( -e "$user[5]/.loginshell" ) {
                        if (!DRY) {
                                unlink "$user[5]/.loginshell" or warn "unlink: 
$!"
                        } else {
                                warn qq{unlink $user[5]/.loginshell\n};
                        }
                }
                                
                if (!DRY) {
                        symlink FROZEN_SHELL, "$user[5]/.loginshell"
                                or warn "symlink: $!";
                } else {
                        warn qq{symlink FROZEN_SHELL, "$user[5]/.loginshell"\n}
                }

                push @{ $$store{$u}{modules} }, 'login';

                if ( -x "/usr/sbin/nscd" ) { system("sudo /usr/sbin/nscd -i 
passwd") };
        }

        elsif ($a =~ /^u/i) {
                if ( $$store{$u}{shell}) {
                        if ( -l "$user[5]/.loginshell" or -e 
"$user[5]/.loginshell" ) {
                                if (!DRY) {
                                        system("rm '$user[5]/.loginshell'");
                                } else {
                                        warn qq{system("rm 
'$user[5]/.loginshell'")\n};
                                }
                        }
                        if (!DRY) {
                                symlink($$store{$u}{shell}, 
"$user[5]/.loginshell")
                                        or warn "symlink: $!";
                        } else {
                                warn qq|symlink($$store{$u}{shell}, 
"$user[5]/.loginshell")\n|;
                        }
                }

                @{ $$store{$u}{modules} } = grep {!/^login$/} @{ 
$$store{$u}{modules} };

                if ( -x "/usr/sbin/nscd" ) { system("sudo /usr/sbin/nscd -i 
passwd") };
        }
}


sub domtool {
        my ($a, $u) = @_;

        # XXX handle all types of domtool privs, not just domains
        # XXX how to restart services after that?

        if ($a =~ /^f/i) {
                my $domains = `domtool-admin perms $u  | grep '^domain: '`;
                chomp $domains;
                my @domains = split / +/, $domains;

                for (@domains) {
                        push @{ $$store{$u}{domains} }, $_;
                        if (!DRY) {
                                system("domtool-admin rmdom $_")
                        } else {
                                warn qq|system("domtool-admin rmdom $_")\n|
                        }
                }

                        if (!DRY) {
                                system("domtool-rmuser $_")
                        } else {
                                warn qq|system("domtool-rmuser $_")\n|
                        }

                push @{ $$store{$u}{modules} }, 'domtool';
        }

        elsif ($a =~ /^u/i) {
                        if (!DRY) {
                                system("domtool-adduser $_")
                        } else {
                                warn qq|system("domtool-adduser $_")\n|
                        }

                for ( @{ $$store{$u}{domains} } ) {
                        if (!DRY) {
                                system("domtool-admin grant $u domain $_")
                        } else {
                                warn qq|system("domtool-admin grant $u domain 
$_")\n|
                        }
                }

                @{ $$store{$u}{modules} } = grep {!/^domtool$/} @{ 
$$store{$u}{modules} };
        }
}



sub cron {
        my ($a, $u) = @_;

        if ($a =~ /^f/i) {
                for ( PUBLIC_ACCESS ) {
                        if ( qx{ssh -K $_ grep -E '^$u\$' /etc/cron.allow }) {
                                push @{ $$store{$u}{cron} }, $_;

                                if (!DRY) {
                                        qx{ssh -K $_ perl -ni -e 'print unless 
/^\$/' /etc/cron.allow }
                                } else {
                                        warn qq{ssh -K $_ perl -ni -e 'print 
unless /^\$/' /etc/cron.allow\n}
                                }
                        }
                }

                push @{ $$store{$u}{modules} }, 'cron';
        }

        elsif ($a =~ /^u/i) {
                for ( @{ $$store{$u}{cron} } ) {
                        if (!DRY) {
                                qx{ssh -K $_ sh -c 'echo $u >> 
/etc/cron.allow'};
                        } else {
                                warn qq{ssh -K $_ sh -c 'echo $u >> 
/etc/cron.allow'\n};
                        }
                }

                @{ $$store{$u}{modules} } = grep {!/^cron$/} @{ 
$$store{$u}{modules} };
        }
}


sub slay {
        my ($a, $u) = @_;

        if ($a =~ /^f/i) {
                for ( PUBLIC_ACCESS ) {
                        if (!DRY) {
                                qx{ssh -K $_ sudo slay $u}; sleep 5; qx{ssh -K 
$_ sudo slay -9 $u};
                        } else {
                                warn qq|ssh -K $_ sudo slay $u; sleep 5; ssh -K 
$_ sudo slay -9 $u\n|
                        }
                }

                push @{ $$store{$u}{modules} }, 'slay';
        }

        elsif ($a =~ /^f/i) {
                @{ $$store{$u}{modules} } = grep {!/^slay$/} @{ 
$$store{$u}{modules} };
        }
}




-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
hcoop-cvs mailing list
hcoop-cvs@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/hcoop-cvs

Reply via email to