e-smith-quota/root/etc/e-smith/events/actions/user-modify-quota

228 lines
6.7 KiB
Plaintext
Raw Normal View History

#!/usr/bin/perl -w
#----------------------------------------------------------------------
# copyright (C) 2002 Mitel Networks Corporation
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# Technical support for this program is available from Mitel Networks
# Please visit our web site www.mitel.com/sme/ for details.
#----------------------------------------------------------------------
package esmith;
use strict;
use Errno;
use Quota;
use esmith::AccountsDB;
my $accounts = esmith::AccountsDB->open;
my @users = ();
my $event = $ARGV [0];
if ($event eq "bootstrap-console-save")
{
# For bootstrap-console-save, make sure that quota entries are
# set for each user
@users = $accounts->users;
}
else
{
# Otherwise just set quota for the named user.
my $userName = $ARGV [1];
#------------------------------------------------------------
# Check the Unix account
#------------------------------------------------------------
=begin testing
use esmith::TestUtils qw(simulate_perl_program);
my $exit = simulate_perl_program($Original_File, 'wibble-event',
'user_that_doesnt_exist');
is( $exit, 255 * 256, 'non-existent user - exit code' );
like( $@, qr{^Account "user_that_doesnt_exist" is not a user account},
' failure message');
$exit = simulate_perl_program($Original_File, 'wibble-event' );
is( $exit, 255 * 256, 'forgotten user - exit code' );
like( $@, qr{^Username argument missing},
' failure message');
=end testing
=cut
die "Username argument missing.\n" unless defined ($userName);
my $user = $accounts->get($userName);
if( !$user or $user->prop('type') ne 'user' )
{
die qq{Account "$userName" is not a user account; modify } .
"user quota failed.\n";
}
@users = ($user);
}
=begin testing
my $a_tmp = '50-e-smith-quota/accounts.conf';
$ENV{ESMITH_ACCOUNT_DB} = $a_tmp;
END { unlink $a_tmp };
open(TMP, ">$a_tmp") || die $!;
print TMP <<'OUT';
root=system|Gid|0|Uid|0
server-manager=url
server-manual=url
shared=system|Gid|500|Visible|internal
shutdown=system
slocate=system|Gid|21
user_quota=user|Gid|1000|Uid|1000|MaxBlocksSoftLim|10000|MaxBlocks|20000|MaxFilesSoftLim|1000|MaxFiles|2000
user_partial=user|Gid|1001|Uid|1001|MaxBlocksSoftLim|123456|MaxFiles|321
user_no_quota=user|Gid|1002|Uid|1002
OUT
close TMP;
# Quota properties in the order setqlim likes.
my @QProps = qw(MaxBlocksSoftLim MaxBlocks MaxFilesSoftLim MaxFiles);
my %curr_quota = (
1000 => { MaxFilesSoftLim => 100 },
1001 => { MaxBlocks => 30000, MaxBlocksSoftLim => 20000 },
1002 => { MaxFiles => 2 },
);
# What we expect the new quotas to be
my %expect_quotas = (
1000 => { MaxBlocksSoftLim => 10000, MaxBlocks => 20000,
MaxFilesSoftLim => 1000, MaxFiles => 2000 },
1001 => { MaxBlocksSoftLim => 123456, MaxBlocks => 30000,
MaxFilesSoftLim => 0, MaxFiles => 321 },
1002 => { MaxBlocksSoftLim => 0, MaxBlocks => 0,
MaxFilesSoftLim => 0, MaxFiles => 2 },
);
{
# Since these users don't really exist, we have to fool getpwnam
# into using the Uid from the dummy accounts DB.
no warnings 'once';
local *CORE::GLOBAL::getpwnam = sub {
esmith::AccountsDB->open->get($_[0])->prop('Uid');
};
# Override the Quota query and set functions since
# 1) these users probably don't exist
# 2) if they did, we don't want to screw with their quotas
# 3) we need to know how each Quota function is called
use Quota;
no warnings 'redefine';
my %query;
sub Quota::query {
my($dev, $uid, $isgrp) = @_;
$query{$uid} = { isgrp => $isgrp };
return (0,
$curr_quota{$uid}{MaxBlocksSoftLim} || 0,
$curr_quota{$uid}{MaxBlocks} || 0,
0,
0,
$curr_quota{$uid}{MaxFilesSoftLim} || 0,
$curr_quota{$uid}{MaxFiles} || 0,
0
);
}
my %set_quota = ();
sub Quota::setqlim {
my($dev, $uid) = (shift, shift);
my(@limits) = splice(@_, 0, 4);
my($tlo) = shift;
my %limits = ();
@limits{@QProps} = @limits;
$set_quota{$uid}{limits} = \%limits;
$set_quota{$uid}{tlo} = $tlo;
return 1;
}
$_STDOUT_ = '';
$_STDERR_ = '';
my $exit = simulate_perl_program($Original_File, 'bootstrap-console-save');
is( $exit, 0, 'bootstrap-console-save - exit code' );
is( $_STDOUT_, '' );
is( $_STDERR_, '' );
is( $@, '' );
is_deeply( [sort keys %set_quota], [sort qw(1000 1001 1002)] );
foreach my $uid (keys %set_quota)
{
is_deeply( $set_quota{$uid}{limits}, $expect_quotas{$uid},
"setqlim for $uid");
}
}
=end testing
=cut
# Quota properties in the order setqlim likes.
my @QProps = qw(MaxBlocksSoftLim MaxBlocks MaxFilesSoftLim MaxFiles);
foreach my $user (@users)
{
my $userName = $user->key;
my $uid = getpwnam($userName);
die qq{Could not get uid for user named "$userName"\n} unless $uid;
my(%uquota, %curr_quota);
foreach my $qprop (@QProps)
{
$uquota{$qprop} = $user->prop($qprop);
}
# Get a $dev value appropriate for use in Quota::query call.
my $dev = Quota::getqcarg("/home/e-smith/files");
# Get current quota settings.
@curr_quota{@QProps} = (Quota::query($dev, $uid, 0))[1,2,5,6];
if( !defined $curr_quota{MaxBlocks} ) # Quota::query failed
{
warn "Cannot query your quota for '$userName' on '$dev'\n";
warn "Quota error (are you using NFS?): ", Quota::strerr(), "\n";
next;
}
# Keep old values unless there are values defined in the account record
foreach my $qprop (@QProps)
{
$uquota{$qprop} = $curr_quota{$qprop}
unless defined $uquota{$qprop};
}
# Set the new quota
Quota::setqlim($dev, $uid, @uquota{@QProps}, 0);
}