228 lines
6.7 KiB
Plaintext
228 lines
6.7 KiB
Plaintext
|
#!/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);
|
||
|
}
|